《Java编程思想》学习笔记-第5章

初始化与清理

当我们说要初始化一个java对象时通常指的是成员变量初始化和构造器(类构造函数)初始化

1.成员变量初始化
  • 基本类型初始化
  • 引用对象初始化
2.构造器初始化
构造器是访问一个java对象的入口,如果类中没有构造器,则编译器会帮你自动创建一个无参构造器(java文档中称为无参构造器,但程序员更习惯叫默认构造器,这个称呼在java语言出来之前就已经有了)。

知识关注点:
一、成员变量初始值问题
public class InitialValues {
	boolean t;
	char c;
	byte b;
	short s;
	int i;
	long l;
	float f;
	double d;
	InitialValues reference;
	
	void printInitialValues() {
		System.out.println("Data type            Initial value");
		System.out.println("boolean              " + t);
		System.out.println("char                 [" + c + "]");
		System.out.println("byte                  " + b);
		System.out.println("short                 " + s);
		System.out.println("int                   " + i);
		System.out.println("long                  " + l);
		System.out.println("float                 " + f);
		System.out.println("double                " + d);
		System.out.println("reference             " + reference);
	}
	
	public static void main(String[] args) {
		InitialValues iv = new InitialValues();
		iv.printInitialValues();
	}
}/* Output:
Data type            Initial value
boolean              false
char                 [ ]
byte                  0
short                 0
int                   0
long                  0
float                 0.0
double                0.0
reference             null
*///:~  

结论:从例子中可以看出, 类的每个成员变量虽然没有指定初始值,但他们确实有初值(char值为0,所以显示空白,Unicode码用0表示空字符);引用对象不指定初始值话,被赋予了一个特殊的值null。

对于 方法局部变量(包括构造函数里面定义的变量),使用前必须指定初始值,如果未指定的话,编译器将报错,像下面的代码
void f() {
	int value;
	value++; //编译器直接报错, The local variable value may not have been initialized
}


二、初始化顺序(代码执行顺序)
class Window {
	Window(int marker) {
		System.out.println("Window("+marker+")");
	}
}

class House {
	int value1;
	static int value2;
	int value3 = 2;
	static int value4;
	
	{
		System.out.println("初始化非静态成员变量:value1 = " + value1 + ", value3 = " + value3);
	}
	
	static {
		value4 = 1;
		System.out.println("初始化静态成员变量:value2 = " + value2 + ", value4 = " + value4);
	}
	
	Window w1 = new Window(1);
	House() {
		System.out.println("House()");
		w3 = new Window(33);
	}
	
	Window w2 = new Window(2);
	void f() {
		System.out.println("f()");
	}
	Window w3 = new Window(3);
}

public class OrderOfInitialization {
	public static void main(String[] args) {
		House h = new House();
		h.f();
	}
}/* Output:
初始化静态成员变量:value2 = 0, value4 = 1
初始化非静态成员变量:value1 = 0, value3 = 2
Window(1)
Window(2)
Window(3)
House()
Window(33)
f()
*///:~ 

new一个类对象时,数据块初始化顺序如下图所示,需要注意的是 静态域只初始化一次(static属于类级别的,该类产生的所有对象共享),随着第一个对象的产生而触发;而 非静态域属于对象级别的,所有每次创建新对象时都会触发一次。 注:如果引入类继承关系,执行顺序会发生变化,不过我们暂时不考虑,在以后的章节中再继续讨论它。


三、方法重载
说方法重载前,我们首先需要区分重载方法,典型案例
void f() {}
int f() { return 1; }
很多人误认为上面的方法是不同的方法,因为它俩看上去确实不太一样,但是编译器却不会让你这样干,为什么呢?
假如使用者这样使用 int value = f(),我们确实可以明确的知道他想调用哪个方法,但是假如他不关心返回值,还想使用第二个方法的逻辑呢,代码是不是就成了这样f(),所以这样编译器就无法区分你想调用哪个方法了。

所以区分方法唯一的途径就是首先看看方法的名字,然后是方法的参数类型,参数类型一样,但是所处的位置不一样的话,编译器也视为不同的方法。例如:
void f(int i, String s) {
     System.out.println("int: " + i + ", String: " + s);
}
void f(String s, int i) {
     System.out.println("String: " + s + ", int: " + i);
}


涉及基本类型重载的问题(基本类型向上转型问题)
import static com.thinking.java.support.Print.*;

public class PrimitiveOverloading {
	void f1(char x) { printnb("f1(char)"); }
	void f1(byte x) { printnb("f1(byte)"); }
	void f1(short x) { printnb("f1(short)"); }
	void f1(int x) { printnb("f1(int)"); }
	void f1(long x) { printnb("f1(long)"); }
	void f1(float x) { printnb("f1(float)"); }
	void f1(double x) { printnb("f1(double)"); }
	
	void f2(byte x) { printnb("f2(byte)"); }
	void f2(short x) { printnb("f2(short)"); }
	void f2(int x) { printnb("f2(int)"); }
	void f2(long x) { printnb("f2(long)"); }
	void f2(float x) { printnb("f2(float)"); }
	void f2(double x) { printnb("f2(double)"); }
	
	void f3(short x) { printnb("f3(short)"); }
	void f3(int x) { printnb("f3(int)"); }
	void f3(long x) { printnb("f3(long)"); }
	void f3(float x) { printnb("f3(float)"); }
	void f3(double x) { printnb("f3(double)"); }
	
	void f4(int x) { printnb("f4(int)"); }
	void f4(long x) { printnb("f4(long)"); }
	void f4(float x) { printnb("f4(float)"); }
	void f4(double x) { printnb("f4(double)"); }
	
	void f5(long x) { printnb("f5(long)"); }
	void f5(float x) { printnb("f5(float)"); }
	void f5(double x) { printnb("f5(double)"); }
	
	void f6(float x) { printnb("f6(float)"); }
	void f6(double x) { printnb("f6(double)"); }
	
	void f7(double x) { printnb("f7(double)"); }
	
	void testConstVal() {
		printnb("5: ");
		f1(5);f2(5);f3(5);f4(5);f5(5);f6(5);f7(5);print();
	}
	
	void testChar() {
		char x = 'x';
		printnb("char: ");
		f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);print();
	}
	
	void testByte() {
		byte x = 0;
		printnb("byte: ");
		f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);print();
	}
	
	void testShort() {
		short x = 0;
		printnb("short: ");
		f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);print();
	}
	
	void testInt() {
		int x = 0;
		printnb("int: ");
		f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);print();
	}
	
	void testLong() {
		long x = 0;
		printnb("long: ");
		f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);print();
	}
	
	void testFloat() {
		float x = 0;
		printnb("float: ");
		f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);print();
	}
	
	void testDouble() {
		double x = 0;
		printnb("double: ");
		f1(x);f2(x);f3(x);f4(x);f5(x);f6(x);f7(x);print();
	}
	
	
	public static void main(String[] args) {
		PrimitiveOverloading p = new PrimitiveOverloading();
		p.testConstVal();
		p.testChar();
		p.testByte();
		p.testShort();
		p.testInt();
		p.testLong();
		p.testFloat();
		p.testDouble();
	}
}/* Output:
5: f1(int)f2(int)f3(int)f4(int)f5(long)f6(float)f7(double)
char: f1(char)f2(int)f3(int)f4(int)f5(long)f6(float)f7(double)
byte: f1(byte)f2(byte)f3(short)f4(int)f5(long)f6(float)f7(double)
short: f1(short)f2(short)f3(short)f4(int)f5(long)f6(float)f7(double)
int: f1(int)f2(int)f3(int)f4(int)f5(long)f6(float)f7(double)
long: f1(long)f2(long)f3(long)f4(long)f5(long)f6(float)f7(double)
float: f1(float)f2(float)f3(float)f4(float)f5(float)f6(float)f7(double)
double: f1(double)f2(double)f3(double)f4(double)f5(double)f6(double)f7(double)
*///:~ 



如果传入的实际数据类型小于方法中声明的形式参数类型时,实际数据类型将会自动被提升。char类型略有不同,直接被提升至int类型(char的范围是0~65535,byte,short是装不下char类型的);另外一个注意的地方是当一个变量值被指定为整型数字时,默认是int类型,所以上面的5当int值处理,浮点数默认是double类型。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值