5.1 用构造器确保初始化
- 创建对象时,如果其具有构造器,Java就会在用户有能力操作对象之前自动调用相应的构造器,从而保证了初始化的进行。
- 构造函数名与类名相同,无返回值,无参数的为无参构造器,可以传参,可以重载。
- 在Java中,”初始化“和”创建“捆绑在一起,两者不能分离
5.2 方法重载
- 区分重载方法
a. 每个重载的方法都必须有一个独一无二的参数类型列表。甚至参数顺序的不同也足以区分两个方法。不过,一般别这么做,因为这会使代码难以维护。 - 涉及基本类型的重载
a. 如果传入的数据类型(实际参数类型)小于方法中声明的形式参数类型,实际数据类型就会被提升。char型略有不同,如果无法找到恰好接受char参数的方法,就会把char直接提升至int型。
b. 如果传入的实际参数较大,就得通过类型转换来执行窄化转换。如果不这样做,编译器就会报错。 - 根据方法的返回值来区分重载方法是行不通的。
5.3 默认构造器
- 如果已经定义了一个构造器(无论是否有参数),编译器都不会帮你自动创建默认构造器
5.4 this关键字
a.pell(1);
//编译器的工作,我们自己不能这么写
Banana.pell(a,1);
- this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用
- this关键字对于将当前对象传递给其他方法也很有用
- 在构造器里调用构造器
a. 尽管可以用this调用一个构造器,但却不能调用两个。此外,必须将构造器调用置于最起始处,否则编译器会报错。
b. 除构造器之外,编译器禁止在其他任何方法中调用构造器。
Flower(){
this("hi",47);
print("在构造器中调用构造器");
}
- static的含义
a. static方法就是没有this的方法
b. 在static方法的内部不能调用非静态方法,反过来倒是可以。
c. 可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法
5.5 清理:终结处理和垃圾回收
- 垃圾回收器只知道释放哪些经由new分配的内存
- 对象可能不被垃圾回收
- 垃圾回收并不等于析构
- finalize()的用途何在
a. 垃圾回收只与内存有关
b. 无论对象时如何创建的,垃圾回收器都会负责释放对象占据的所有内存。一种例外情况,通过某种创建对象方式以外的方式为对选哪个分配了存储空间。
c. 主要应用在调用本地方法(C/C++中的代码)时,需要使用free()之类的函数释放内存 - 无论是“垃圾回收”还是“终结”,都不保证一定会发生。如果Java虚拟机(JVM)并未面临内存耗尽的情形,他还是不会浪费时间去执行垃圾回收以恢复内存的。
- 终结条件,用finalize()可以检测出不满足条件的对象
- 垃圾回收器对于提高对象的创建速度,具有明显的效果
- 垃圾回收器工作时,一面回收空间,一面使堆中的对象紧凑排列,这样“堆指针”就可以很容易移动到更靠近传送带的开始处,也就尽量避免了页面错误。通过垃圾回收器对对象重新排列,实现了一种高速的、有无限空间可分配的堆模型。
a. 引用计数是一种简单但速度很慢的垃圾回收技术。
b. JVM的一些知识
5.6 成员初始化
- Java尽力保证:所有变量在使用前都能得到恰当的初始化。对于方法的局部变量,Java以编译时错误的形式来贯穿这种保证。
- 类的每个基本类型数据成员保证都会有一个初始值
- 指定初始化:Java在类中指定字段初始值,但在C++中不行
5.7 构造器初始化
- 无法阻止自动初始化的进行,它将在构造器被调用之前发生。
- 初始化顺序:在类的内部,变量定义的先后顺序决定了初始化的顺序,但都是在方法定义之前定义
- 静态数据的初始化:静态初始化只有在必要时刻才会进行,当创建的第一个对象对静态数据初始化了,后面的对象就不会对其进行初始化。
- 即使没有显示地使用static关键字,构造器实际上也是静态方法。(构造器可以看成静态方法)
- 显示的静态初始化
a. Java允许将多个静态初始化动作组织成一个特殊的“静态子句”(有时也叫做“静态块”)
public class Spoon{
static int i;
static {
i = 47;
}
}
这段代码只执行一次:当首次生成这个类的一个对象时,或者首次访问属于那个类的静态数据成员时(即便从没发生过那个类的对象)。
6. 非静态实例初始化:这种语法对于支持“匿名内部类”的初始化是必须的,但是它也使得你可以保证无论调用了哪个显示构造器,某些操作都会发生。
5.8 数组初始化
- 数组定义,Java中可以将一个数组赋值给另一个数组
int[] a1; //常用
int a[];
- 编译器不允许指定数组的大小。数组初始化
int[] a1 = {1, 2, 3, 4, 5};
a1 = new int[5];
- 可变参数列表
a. 一般使用Object类型作为祖先类型
b. 当int类型和Integer类型同时存在时,会将int提升为Integer
public class Main {
static void printArray(Object... args){
for(Object obj : args){
System.out.println(obj +" ");
}
System.out.println();
}
public static void main(String[] args) {
printArray(new Integer(47), new Float(3.14), new Double(11.11));
printArray(47, 3.14F, 11.11);
printArray("one", "two", "three");
printArray((Object[])new Integer[]{1, 2, 3, 4}); //传入Object类型,可以通用
printArray();
}
}
//结果
47
3.14
11.11
47
3.14
11.11
one
two
three
1
2
3
4
5.9 枚举类型
- enum关键字来定义枚举类型
public enum Spiciness{
NOT, MILD, MEDIUM, HOT, FLAMING
}
- 枚举量为常量,应该使用大写
- 大体上,你可以将enum用作另外一种创建数据类型的方式,然后直接将所得到的类型拿来使用
5.10 总结
- 初始化在Java中占有至关重要的地位
- 由于要保证所有对象都被创建,构造器实际上要比这里所讨论的更加复杂