1.Java程序初始化的执行顺序:
父类静态变量—>父类静态代码块—>子类静态变量—>子类静态代码块—>父类非静态变量—>父类非静态代码块—>父类构造方法—>子类非静态变量—>子类非静态代码块—>子类构造方法
2.integer与int比较时注意事项
①无论如何,Integer与new Integer不会相等。不会经历拆箱过程,
②两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false
java在编译Integer i2 = 128的时候,被翻译成-> Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存
③两个都是new出来的,都为false
④int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比
3.自动数据类型转换
低 ---------------------------------------------> 高
byte,short,char-> int -> long -> float -> double
4.线程状态转换简洁版
5.javac的作用
javac将源程序编译成.class文件,字节码;java将字节码转为机器码,.exe程序
6.equals()方法注意事项
比较值相等之前会先比较类型是不是一样;如果类型一样才会比较值;如果类型不一致就直接return false;
7.StringBuffer和StringBuidler
1.StringBuffer和StringBuilder的默认大小为16
2.length 返回当前长度
如果字符串长度没有初始化长度大,capacity返回初始化的长度
如果append后的字符串长度超过初始化长度,capacity返回增长后的长度
8.关于jvm方法区
类信息、常量、静态变量等数据储存在方法区,只会在类加载的时候储存一次,地址一样,他们是线程共享的。
9.继承
1.构造函数是不能继承的,只是用来在子类调用,(如果父类没有无参构造函数,创建子类时,必须在子类构造函数代码体的第一行显式调用父类的有参数构造函数,否则不能编译);
2.如果父类没有有参构造函数,那么在创建子类时可以不显式调用父类构造函数,系统会默认调用父类的无参构造函数super();
3.java中静态属性和静态方法可以被继承,但是没有被重写(overwrite)而是被隐藏.
4.对于父类private属性和方法,子类一定继承但不能访问。
10.解决hash冲突的四大方法
开放定址法(如ThreadLocal)、链地址法(拉链法)(如HashMap)、再哈希法、建立公共溢出区
11.final关键字注意事项
使用 final 关键字修饰一个变量时,是指引用变量不能变(也就是指向的地址),引用变量所指向的对象中的内容还是可以改变的。
例如
final StringBuffer sb = new StringBuffer();
sb.append("hello");
12.HashMap与HashTable
Hashtable:
(1)Hashtable 是一个散列表(哈希表),它存储的内容是键值对(key-value)映射。
(2)Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。
(3)HashTable直接使用对象的hashCode。
HashMap:
(1)由数组+链表组成的,基于哈希表的Map实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。
(2)不是线程安全的,HashMap可以接受为null的键(key)和值(value)。
(3)HashMap重新计算hash值
13.关于sleep(),wait(),yield(),join()方法
1.sleep()方法是让当前运行这一句的代码休眠指定的一段时间,在休眠时间里,线程不会获取CPU的执行权,如果当前线程持有了对象锁,是不会释放对象锁的,过了休眠时间线程自动转为可运行状态。sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会。线程执行sleep()方法后转入阻塞(blocked)状态。
2.wait()方法是让当前线程等待一段时间,这段时间里,线程将一直处于阻塞状态,直到被notify()或者notifyAll()方法唤醒,如果线程持有对象锁,会释放对象锁,wait()和notify()方法都是object对象的方法,而不是线程独有的方法,另外,wait()和notify()方法运行时必须持有锁(即代码要是同步的),否则会报错,wait()会释放锁也是因为notify()要得到锁,但是notify()方法并不会释放锁,所以一般把notify()放在代码最后。
3.yield()不会释放锁,只是通知调度器自己可以让出cpu时间片,但只是建议,调度器也不一定采纳。一个线程调用yield方法,可以使具有相同优先级线程获得处理器。执行yield()方法后线程转入就绪(ready)状态。
4.在一个线程A中运行了线程B的join()方法,则线程A必须等到线程B执行完后才能开始执行,可以用于保证线程的执行先后顺序,而join()有资格释放资源其实是通过调用wait()来实现的。
14.动态单分配与静态多分派
普通方法,运用的是动态单分配,是根据new的类型确定对象,从而确定调用的方法;
静态方法,运用的是静态多分派,即根据静态类型确定对象,因此不是根据new的类型确定调用的方法
例子
public class Father {
public void say(){
System.out.println("father");
}
public static void action(){
System.out.println("爸爸打儿子!");
}
}
public class Son extends Father{
public void say() {
System.out.println("son");
}
public static void action(){
System.out.println("打打!");
}
public static void main(String[] args) {
Father f=new Son();
f.say();
f.action();
}
}
输出:son
爸爸打儿子!
当调用say方法执行的是Son的方法,也就是重写的say方法
而当调用action方法时,执行的是father的方法。
15.面向对象的五大基本原则
单一职责原则(SRP)
开放封闭原则(OCP)
里氏替换原则(LSP)
依赖倒置原则(DIP)
接口隔离原则(ISP)
16.关于byte溢出
其实可以把每个数据类型范围画成一个圈,byte是从-128-127,可以这样想,从-128开始,向上加就是一步一步画圈,知道加到127,这个圆圈刚好补满了,所以127再加一就又到了-128,再加一就是129,也就是-127
16.方法调用完后注意事项
方法调用时,会创建栈帧在栈中,调用完是程序自动出栈释放,而不是gc释放。Java 的垃圾回收器(GC)主要针对堆区,所以在栈区中的方法调用就不会由GC释放
17.java中方法的重写的两同两小一大原则
方法名相同,参数类型相同
子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
子类访问权限大于等于父类方法访问权限。
18.值传递和引用传递
1.值传递不可以改变原变量的内容和地址;
2.引用传递不可以改变原变量的地址,但可以改变原变量的内容;
19.关于内部类
1.静态内部类才可以声明静态方法
2.静态方法不可以使用非静态变量
3.抽象方法不可以有函数体
4.局部内部类是放在代码块或方法中的,不能有访问控制的修饰符,且不能用static进行修饰。
20.关于精度丢失
精度丢失只会发生在从大范围到小范围的转换,如 double 到 int ,也就是从大范围到小范围。