16. 静态域:类的域,在类加载到虚拟机上时被执行。
17. 显式域初始化:在调用构造器之前,先执行赋值操作。
class Employee {
private int id = makeId();
private int t = 2;
private int makeId()
{
return ++t;
}
public int getId()
{
return id;
}
}
上述代码中,id的值在对象生成后为1,t值为2。注意这些初始化过程是在构造函数调用之前完成的。有人问为什么id不是3呢?这就要清楚整个类的初始化次序了,请看下面。
18. 调用构造器的具体处理步骤:
1)所有数据域被初始化为默认值(0, false或null)
2)按照在类声明中出现次序,依次执行所有域初始化语句和初始化块。
3)执行构造函数主体
19. 对static变量的static初始化块;
static {
} <-- 在类第一次加载时,就进行初始化,以后不进行。
20. final修饰方法和类表示阻止继承
final类中方法自动成为final, 而不包括域。
final方法不允许在子类中重新定义。
还有一个final的注意点,这是在java并发中提到的,对于在构造函数内对final变量进行初始化,有如下规则:生成对象并将引用赋给变量之前,final变量一定已经完成构造,这是JMM的final重排序规则,这里简单提一下,以后再详细介绍。
21. 抽象类,抽象方法
有抽象方法的类必须显式定义为abstract类。
抽象类可以无抽象方法。
抽象类中域可以public也可以private,看情况。
抽象类可以声明,但不能实例化对象,可以引用非抽象类。
将抽象类的子类赋给抽象类变量时,只能使用抽象类中定义的方法,和多态是一样的。
对于接口而言,接口只能有抽象方法,且所有属性都为public。
22. 对象包装器与自动装箱
Integer类等一系列基本变量的包装类,在需要基本变量的地方是自动拆箱,在需要类变量的地方是自动装箱。
自动装拆箱是编译器认可的,而不是虚拟机。
23.java不支持析构器
但可以为任何一个类添加finalize方法,finalize方法讲在垃圾回收器清除对象之前调用。不要依赖finalize方法,因为对象何时清理很难确定。
24. 定义简单泛型类
25. 泛型方法
泛型方法可以定义在泛型类中,也可以定义在普通类中。
26. 类型变量的限定
public static <T extends Comparable> T min(T[] a);
T 和绑定类型可以是类,也可以是接口。
T是绑定类型的子类型。
T extends Comparable & Serializable, 注“,”用于分隔类型变量可以有多个绑定类型,但是最多只能有一个接口类型。同时,它必须是限定列表的第一个。
27. 无论何时定义一个泛型类型,都自动提供一个相应的原始类型。在虚拟机没有泛型类型对象-----所有对象都属于普通类。
原始类型用第一个限定的类型变量来替换,若没有给限定就用object替换。Pair<T>中没有显式限定,就用object替换T。
注:在C++中每个模板的实例化产生不同类型,这将导致代码膨胀。
java不存在这个问题的困扰。
28. 当程序调用泛型方法时,如果擦除返回类型,编译器插入强制类型转换。
29. 泛型方法中任意合成的桥方法,发生在继承泛型类中。多态与类型擦除发生了冲突。桥方法被合成来保存多态。
为了保持类型安全性,必要时插入强制类型转换。
30. java泛型会有一些限制(由类型擦除引起的):
1)不能用基本变量实例化类型参数
2)运行时类型查询只适用于原始类型 : instanceof
3) 不能创建参数化类型的数组
31. 如果想在一个构造方法中调用另一个构造方法,那么可以使用this()的方式调用,this()括号中的参数表示目标构造方法的参数。this()必须要作为构造方法的第一条语句,this()之前不能有任何可执行的代码。
32. Object[]不能强制转换成Integer[]类型。
Integer[]是一个对象继承了Object类型,非Object[]类型。
34. System.out.println(obj); 会自动调用obj.toString()方法。
35. ArrayList底层用数组实现,如果不加参数调用构造函数,会在底层实现一个10元素的Object数组,如果增加的元素个数超过10个,那么ArrayList底层会新生成一个数组,长度为原数组的1.5倍加1,然后将原数组内容拷贝到新数组中。
36.remove()中调用System.arrayCopy()代价比较高。insert()调用代价也比较高。
37. LinkedList和ArrayList都是实现了List接口的类。
LinkedList中由节点构成的。
java中引用代替了指针。
LinkedList用的是双向链表实现的。
38. java的集合框架:
39. HashSet中加入的对象排异性是针对具体对象类而言的,不是对象中的值。具体通过equals()方法来判断。比如添加自己的类(要实现自己的equals方法)。
40. Object类的hashCode()方法的特点:
a)在java应用的一次执行过程中,对于同一个对象的hashCode()方法的多次调用,他们应该返回同样的值(前提是对象的信息没有发生变化)。
b) 对于两个对象来说,如果使用equals方法比较返回true,那么这两个对象的hashCode值一定是相同的。
C)对于两个对象来说,如果equals方法比较返回false,那么这两个对象的hashCode值不要求一定不同,但是不同则一定可以提高性能。
d)对于object类来说,不同的object对象的hashcode值是不同的(hashCode值表示对象的地址)。