Java笔记

java程序编译后会生成字节码文件,就是.class文件
final并不能修饰抽象类
final修饰的类可以被重载但不能被重写
线程的启动方式只能通过start这种方式启动才能真正的实现多线程的效果,如果是手动调用run方法和普通方法调用没有区别
线程安全的map:HashTable,SynchronizedMap,ConcurrentHashMap
volatile能保证数据的可见性,但不能完全保证数据的原子性; synchronized即保证了数据的可见性也保证了原子性
如果希望监听TCP端口9000,服务器端应该怎样创建socket?
- new ServerSocket(9000);
float f = 45.0; 小数如果不加 f 后缀,默认是double类型。double转成float向下转换,意味着精度丢失,所以要进行强制类型转换。
Double d = 100; int类型不能转型为Double,最多通过自动装箱变为Integer但是Integer与Double没有继承关系,也没法进行转型
instance是java的二元运算符,用来判断他左边的对象是否为右面类(接口,抽象类,父类)的实例

class A{
    static {
        System.out.println("父类静态代码块");
    }
    public A(){
        System.out.println("父类构造方法");
    }
    {
        System.out.println("父类初始化块");
    }
}
public class B extends A{
    static{
        System.out.println("子类静态代码块");
    }
    public B(){
        System.out.println("子类构造方法");
    }
    {
        System.out.println("子类初始化块");
    }
    public static void main(String[] args){
        new B();
    }
}

父类静态代码块-->子类静态代码块-->父类普通代码块-->父类构造方法-->子类代码块-->子类构造方法;

 

“import java.scut.computer;” 必须放在代码非注释的第一行
System.out.println(14^3); 同0异1
如果还有其他线程,main thread结束后jvm不会让程序退出

public class Example{
String str=new String("hello");
char[]ch={'a','b'};
public static void main(String args[]){
  Example ex=new Example();
  ex.change(ex.str,ex.ch);
  System.out.print(ex.str+" and ");
  System.out.print(ex.ch);
}
public void change(String str,char ch[]){
  str="test ok";
  ch[0]='c';
}
}
// hello and cb

*** 数组是引用传递

public>protcted(同类,包,子类)>default>priavte

 

public class Test {
    public static void main(String[] args) {
        System.out.println(test()); // 4. return tmp = 2
 
    }
    private static int test() {
        int temp = 1;
        try {
            System.out.println(temp); // 1. temp = 1
            return ++temp; // 2. save tmp = 2
        } catch (Exception e) {
            System.out.println(temp);
            return ++temp;
        } finally {
            ++temp; // 3. temp = 3, if have return, update tmp
            System.out.println(temp);
        }
    }
}

 

public class Demo {
    public static String sRet = "";
    public static void func(int i)
    {
        try
        {
            if (i%2==0)
            {
                throw new Exception();
            }
        }
        catch (Exception e)
        {
            sRet += "0";
            return;
        } 
        finally
        {
            sRet += "1";
        }
        sRet += "2";
    }
    public static void main(String[] args)
    {
        func(1); // finally + 1 + 2
        func(2); // catch 0 + finally 1 + return 
        System.out.println(sRet);
    }
}

 

class Base
{
    public void method()
    {
        System.out.println("Base");
    } 
}
class Son extends Base
{
    public void method()
    {
        System.out.println("Son");
    }
     
    public void methodB()
    {
        System.out.println("SonB");
    }
}
public class Test01
{
    public static void main(String[] args)
    {
        Base base = new Son(); // 向上转型,父类引用无法调用子类的独有方法
        base.method(); // 运行时调用son方法
        base.methodB(); // 编译失败,父类没有方法
    }
}

编译看左边,运行看右边:编译看左边有没有这个方法,运行调用右边的方法


假定Base b = new Derived(); 调用执行b.methodOne()后,输出结果是什么?

public class Base
{
   public void methodOne()
   {
      System.out.print("A");
      methodTwo();
   }
 
   public void methodTwo()
   {
      System.out.print("B");
   }
}
 
public class Derived extends Base
{
   public void methodOne()
   {
      super.methodOne();
      System.out.print("C");
   }
 
   public void methodTwo()
   {
      super.methodTwo();
      System.out.print("D");
   }
}
// ABDC

 

byte 1个字节
short 2个字节
int 4个字节
long 8个字节
float 4个字节
double 8个字节
char 2个字节
1. 在try中调用System.exit(0),强制退出了程序,finally块不执行。
2. 在进入try块前,出现了异常,finally块不执行。
final修饰变量,变量的引用(也就是指向的地址)不可变,但是引用的内容可以变(地址中的内容可变)
final int[] array = {1, 2, 3, 4, 5};
array[0] = 10;
泛型只在编译的时候保证数据类型的正确性,增加可读性,和运行期间的性能无关
FileInputStream,InputStream为节点流。BufferedInputStream,DataInputStream为处理流
如果父类中只有有参构造器,则子类必须super显示调用
wait():等待时线程别人可以用。

sleep():等待时线程还是自己的,别人不能用。

yield():释放锁,同优先级的其他线程有机会获得锁。

Math.round(11.5) 等于多少 (). Math.round(-11.5) 等于多少
四舍五入是往大数方向入:12 -11
-12 % -5 = -2
模运算余数的符号跟被除数符号相同
static可以用来修饰内部类,但是不可以用来修饰外部类
反射破坏代码的封装性,破坏原有的访问修饰符访问限制

在接口中,属性默认public static final,这三个关键字可以省略;
在接口中没有静态块和构造器,接口中的属性是必须直接赋值的
线程调度分为协同式调度和抢占式调度,Java使用的是抢占式调度,也就是每个线程将由操作系统来分配执行时间,线程的切换不由线程本身来决定(协同式调度)。
抽象类不一定含有抽象方法,接口中的方法都是抽象方法。

public static void main(String args[]) {
    byte a = 127;
    byte b = 127;
    a+=b;
    System.out.println(b);
}

char、byte、short相加时会自动转换为int类型,所以:b = (byte)(a + b) 

+=会自动进行强转,相当于加了(byte); 

byte越界,但首尾相接,不影响编译

 写法上:中间的[]必须有值

调用构造函数之前需要使用new实例化对象,否则用this方法调用。

public class Base{
int w, x, y ,z;
public Base(int a,int b)
{
    x=a; y=b;
}
public Base(int a, int b, int c, int d)
{
    // assignment x=a, y=b
    w=d;z=c;
}}
在代码说明// assignment x=a, y=b处写入如下哪几个代码是正确的?()

这里不可以使用Base(a,b), 应该是this(a,b)

run(): execution
start(): ready but not execution
String s = “a” + “b” + “c” + 360;编译器将其优化为String s = “abc360”,若常量池中不存在这个字符串则会常量池中创建一个对象,若存在则不创建
所以只创建了一个对象
Object has wait()/finalize()

Integer a = 1;
Integer b = 1;
Integer c = 500;
Integer d = 500;
System.out.print(a == b);
System.out.print(c == d);
一、包装类和基本数据类型在进行“==”比较时,包装类会自动拆箱成基本数据类型,integer(0)会自动拆箱,结果为true

二、两个integer在进行“==”比较时,如果值在-128和127之间,结果为true,否则为false

三、两个包装类在进行“equals”比较时,首先会用equals方法判断其类型,如果类型相同,再继续比较值,如果值也相同,则结果为true

java中做了下标检测,所以不会出现数组越界,也就避免了数据覆盖。C/C++中不检查数组越界,有数据覆盖风险。
"string" + (int)8 = string
java用监视器机制实现了线程之间的同步执行
- 监视器(Monitor)是通过关键字 synchronized 来实现的
Java的Daemon线程,setDaemon( )设置必须要? start前
读写平均怎么加锁:
A,只对写操作加锁,不对读操作加锁,会造成读到脏数据
B,CopyOnWrite的核心思想是利用高并发往往是读多写少的特性,对读操作不加锁,对写操作,先复制一份新的集合,在新的集合上面修改,然后将新集合赋值给旧的引用。这里读写平均,不适用
C,分段加锁,只在影响读写的地方加锁,锁可以用读写锁,可以提高效率
ThreadLocal使用开放定址法解决hash冲突,hashmap使用链地址法解决hash冲突

在java中,我们可以用违例(Exception)来抛出一些并非错误的消息,但这样比直接从函数返回一个结果要更大的系统开销。
=> 方法返回:stack,异常:heap,开销大
java接口包含函数声明和变量声明。
=> public static final 常量

class HasStatic{
    private static int x = 100;
    public static void main(String args[ ]){
        HasStatic hs1 = new HasStatic();
        hs1.x++; // 101
        HasStatic hs2 = new HasStatic();
        hs2.x++; // 102
        hs1=new HasStatic();
        hs1.x++; // 103
        HasStatic.x--; // 102
        System.out.println( "x=" +x);
    }
}

1. 可以通过实例访问static变量

2. static变量无论被多少个实例访问都是同一个

public class Test {
    private String name = "abc";
    public static void main(String[] args) {
        Test test = new Test();
        Test testB = new Test();
        String result = test.equals(testB) + ",";   // false
        result += test.name.equals(testB.name) + ","; //true
        result += test.name == testB.name;  // true, the same "abc"
        System.out.println(result);
    }
}

首先test.equals(testB),Test类并没有重写equals方法,那么在比较时,调用的依然是Object类的equals()方法,比较的是两个对象在内存中的地址,结果为false。

在test对象初始化时,JVM会先检查字符串常量池中是否存在该字符串的对象,此时字符串常量池中并不存在"abc"字符串对象,JVM会在常量池中创建这一对象。当testB被创建时,同样会执行private String name = "abc";,那么此时JVM会在字符串常量池中找到test对象初始化时创建的"abc"字符串对象,那么JVM就会直接返回该字符串在常量池中的内存地址,而不会新建对象。

成员可以和局部重名,this来引出成员变量

一个Java源程序文件中定义几个类和接口,则编译该文件后生成几个以.class为后缀的字节码文件。(错)

这个题目是说一个Java源程序中有n个类和接口,就会生成n个以.class为后缀名的文件,但是它忽略了在类和接口里面还可以定义内部类和匿名内部类,这个时候就不仅仅是n个了,还需要加上定义了多个内部类和匿名内部类。

import java.util.Date; 
package teat
public class SuperTest extends Date{ private static final long serialVersionUID = 1L; private void test(){ System.out.println(super.getClass().getName()); } public static void main(String[]args){ new SuperTest().test(); } }

super是Date,getClass是Object的方法,指的是runtime时的class -> 即子类的SuperTest

getName()返回包名+类名: test.SuperTest

如果是想返回Date的名称可以用 super.getClass().getSuperClass().getName();

String s1 = "coder";     
String s2 = "coder";     
String s3 = "coder" + s2;     // not in the constant pool, but in the heap
String s4 = "coder" + "coder";     
String s5 = s1 + s2;            
System.out.println(s3 == s4); // FALSE
System.out.println(s3 == s5);  // FALSE, difference objects in the heap
System.out.println(s4 == "codercoder"); // TRUE
// new关键字每执行一次在堆内存中创建一个对象,new String("coder")也是堆里

 类方法 = static 方法

int a = '2'  => a = 50

常用ASCII码值:空格为32;数字0为48;“A”为65;“a”值为97。

 方法重载对返回值没有要求:public void  example(){...} => 可以是 public int example(int a){...}

下面哪种情况会导致持久区jvm堆内存溢出? 
- 使用CGLib技术直接操作字节码运行,生成大量的动态类

持久代一般存放了要加载的类信息、静态变量、final类型的常量、属性和方法信息。
持久代想要溢出,与创建对象的,大量运行字符串没关系。只有操纵调用,类信息的东西才会影响到持久代。
类信息对应的就是操纵动态生成类等等。
HashMap可以用null值和空字符串作为Key,不过只能有一个
Hashtable 是一个哈希表,该类继承了 Dictionary,实现了 Map 接口; key不可以null

public class P {
    public static int abc = 123;
    static{
        System.out.println("P is init");
    }
}
public class S extends P {
    static{
        System.out.println("S is init");
    }
}
public class Test {
    public static void main(String[] args) {
        System.out.println(S.abc);
    }
}
=> P is init<br />123

不会初始化子类的几种

1. 调用的是父类的static方法或者字段
2.调用的是父类的final方法或者字段
3. 通过数组来引用
 
checked exception:指的是编译时异常,该类异常需要本函数必须处理的,用try和catch处理,或者用throws抛出异常,然后交给调用者去处理异常。
runtime exception:指的是运行时异常,该类异常不必须本函数必须处理,当然也可以处理。
Thread.sleep()抛出的InterruptException属于checked exception;IllegalArgumentException属于Runtime exception

 

        public class Demo {
    public static void main(String[] args) {
        Collection<?>[] collections = 
{new HashSet<String>(), new ArrayList<String>(), new HashMap<String, String>().values()};
                Super subToSuper = new Sub();
                for(Collection<?> collection: collections) {
    System.out.println(subToSuper.getType(collection));
}
}
abstract static class Super {
    public static String getType(Collection<?> collection) {
        return “Super:collection”;
}
public static String getType(List<?> list) {
        return “Super:list”;
}
public String getType(ArrayList<?> list) {
        return “Super:arrayList”;
}
public static String getType(Set<?> set) {
        return “Super:set”;
}
public String getType(HashSet<?> set) {
        return “Super:hashSet”;
}
}
static class Sub extends Super {
    public static String getType(Collection<?> collection) {
            return "Sub"; }
}
}

Super:collection Super:collection Super:collection

原因:调用static方法,在编译时已经决定了使用super的方法!Super subToSuper = new Sub(); 左编译右运行

是使用父类的Super static 方法。如果修改成成员方法,答案就是SubSubSub, 运行时决定!

class A{
    public A foo() {
        return this;
    }
}
class B extends A {
    public A foo(){
        return this;
    }
}
class C extends B {
    _______
 
}

可以放入到横线位置,使程序正确编译运行,而且不产生错误的选项是( )

A
public void foo(){}              
B
public int foo(){return 1;}              AB 方法名+参数 和父类一致 => 重写! 返回值不是父类的子类或者同类型 => 编译错误!
C
public A foo(B b){return b;}    不是重写!
D
public A foo(){return A;}           本身错误
方法的重写需要满足:三同一大一小(方法名、返回值类型、形参相同;访问权限>=重写前;抛出异常<=重写前)
import java.util.* => 能访问java/util目录下的所有类,不能访问java/util子目录下的所有类
Object o1 = true new Integer(1) : new Double(2.0); => 1.0
三元操作符如果遇到可以转换为数字的类型,会做自动类型提升
Collection是java容器对象的顶层接口,想List,Set等都实现了Collection接口
Collections是java集合对象的工具类,提供了有关常用集合操作的静态方法
 
posted @ 2024-02-29 21:51  PEAR2020  阅读(13)  评论(0)    收藏  举报