《JAVA编程思想(第四版)》第五章(初始化与清理)小结

1.1构造器的作用:确保初始化.

规定名称与类名相同.所以"每个方法首字母小写"的编码风格并不适用于构造器.

public class dog {
	String name;
	public dog() {
		System.out.println("生成一只狗!");
		name = "dog";
		System.out.println("给狗命名为" + name);
	}
        public static void main(String[] args) {
		//生成10只狗
		for (int i = 0; i < 10; i++) {
			new dog();
		}
	}
}

/**
生成一只狗!
给狗命名为dog
...8次...
生成一只狗!
给狗命名为dog

*/

很简单的可以看出,每次new一个对象的时候,就是通过构造器生成一个对象,我们可以在构造器中初始化属性.

构造器可以有多个.比如我们不满意上面的狗名全是dog,可以增加一个参数,改变狗名字.这说明:构造器支持重载.

public class dog {
	String name;
        public dog(int n) {
		System.out.println("生成一只狗!");
		name = "dog" + n;
		System.out.println("给狗命名为" + name);
	}
	
	public static void main(String[] args) {
		//生成10只狗
		for (int i = 0; i < 10; i++) {
			new dog(i);
		}
	}
}
/**
生成一只狗!
给狗命名为dog0
...1--8....
生成一只狗!
给狗命名为dog9

*/

1.1.1重载方法的小tips

  1. 同一个类中的方法的名字相同时,参数不同(包含顺序,个数,类型.etc)时,即为重载方法.
  2. 重载时,应该注意类型提升问题,
    1. 当使用byte,short,等参数依次遍历重载方法,当遇到可以被兼容的类型(例如:int)时,立刻调用方法,无视剩余方法,
    2. char类型则是遍历寻找参数为:char的方法,如果没有找到,也将提升为int类型.
  3. 返回值并不能区分重载方法.他们可能相同,也可能不同.

1.1.2默认构造器

在程序员没有写构造器的时候,编译器会添加一个默认的构造器,方法参数为空,方法体为空.

当程序员为某类写一个及以上的构造器时,编译器将不再为该类添加构造器.

1.2this关键字

假如你期望在方法内部获取到当前对象,那么this关键字就是java提供的手段.

public class TestThis {
        String name = "test";
	public void a(){
		
	}
	void b() {
		this.a();//调用当前对象的a()方法
                //但是往往我们更喜欢直接使用,二者是等价的,并且后者确实更实用.
                a();
                //因为编译器会帮我们改变a()为:this.a()
	}
	void c(String name){
                //此时参数名与类的字段名重复,可以使用this关键字区分
                this.name = name;
                //this表示该对象,所以this.name表示:该对象的name
        }
}

1.2.1构造器中调用构造器.

public class ReConstructor {
	String name;
	int flag;

	public ReConstructor() {
		this("defaltName", 999);
		// 注意:必须放在第一行.
	}
	public ReConstructor(String name, int flag) {
		this.name = name;
		this.flag = flag;
	}
}

千万注意:一定要把this调用构造器放在第一行,否则将会报错.

2.清理:终结处理和垃圾回收

2.1 GC回收的tips

Java中的对象并非总是被垃圾回收,或者或:

  1. 对象可能不被垃圾回收.
  2. 垃圾回收并不等于C++语言中的"析构".
  3. 垃圾回收只与内存有关.
  4. 完全由JVM判断,程序员只能提出建议.
  5. 如果JVM并未面临内存耗尽的情形,他是不会浪费时间去执行垃圾回收以回复内存的.

举个小例子:char[ ] 往往比String 更安全,因为String为不可变,当我们以为它消失的时候,GC并未启动,此时String的数据仍在内存中.而char数组可以被覆盖.(GC只在内存快要耗尽的情况下启动,因为太过频繁的回收将拖累整个效能).

2.2垃圾回收器如何工作.

篇幅过多,只简单说

  1. JVM在内存耗尽时,启动GC,回收垃圾.
  2. 而由于GC的存在.提高了对象的创建速度
  3. 平时GC使用"标记--清扫"模式,当检测到堆空间出现很多碎片,就会切换到"停止--复制"模式

3成员初始化

Java尽力保证:所有变量在使用前都能得到恰当的初始化.对于方法的局部变量,Java以编译时错误的形式来贯彻这种保证.

public class InitData {
	public static void main(String[] args) {
		int i;
		i++;	//异常:The local variable i may not have been initialized	
		//编译时异常,即变量未初始化.
		System.out.println(i);	//输出 0
		//这样是对的,因为编译器赋默认值i = 0,但是编译器无法保证是否是由于程序员的疏忽,所以上一句为错.
	}
}

初始化的顺序也应该被注意.不要出现向前引用的情况.

public class InitData {
	int  j = g(i);	//报错,因为此时 i 还未定义
	int i =f();
	int f() {
		return 1;
	}
	int g(int i) {
		return i*i;
	}
}

3.1构造器初始化.

public class InitData {
	int i = 11;//调用任何构造器之前,i的值已经在这里被初始化了.

	public InitData() {
		System.out.println(this.i);
		i = 7;//初始化i的值.
                //两次初始化拥有先后顺序,这可以很好地保证变量被初始化了.
	}
	
	public static void main(String[] args) {
		new InitData();	//输出11
	}
}

现在最好可以记住两次初始化的顺序,后来的继承初始化的顺序容易被混淆.

猜你喜欢

转载自blog.csdn.net/m0_37961948/article/details/81128571