Thinking in Java 笔记: Initialication & Cleanup

成员变量和局部变量初始化:
成员变量若不显式初始化java会默认对其初始化:0,'\u0000',false,null...
局部变量必须显式初始化后才能使用,否则有编译期错误

关于方法overload:
[list]
[*]每一个重载的方法都必须有一个独一无二的的参数类型列表
[*]形参顺序的不同也会导致参数列表的不同
[*]返回值不能区分重载方法.(若有
int f(){
return 1;
}
void f(){};
当你在程序中只调用f()时,编译器不能确定你调用的是哪个方法),所以:方法名和参数表的组合(不包含返回值)在一起唯一地标识某个方法.[/list]
涉及基本数据类型的重载:
[list]
[*]如果传入的基本数据参数的类型"小于"重载方法所声明的形参,实际参数类型就会被提升.(若有方法void f(double d){};当调用f(5)时,在方法执行过程中int类型的5被自动提升为double.
[*]如果传入的基本数据参数的类型"大于"重载方法所声明的形参,必须在调用时候做类型转换,否则编译报错(若有方法void f(int i){};double d = 5d;若调用f(d)编译报错,必须做显示类型转换f((int)d);因为这样可能导致信息丢失)
[/list]
关于this:
当对象调用一个方法时,编译器在幕后把所操作对象的引用作为第一个参数传递给这个方法.(若有
Banana a = new Banana();// Banana有个方法void f(int i){}
则a.f(5)在内部表示为Banana.f(a,5),如果你希望在方法内部获得对当前对象的引用,你可以使用this来表示.
所以:this关键字只能在非静态的方法中使用,表示"调用方法的那个对象的引用".
此外,如果为this添加了参数列表,将产生对符合此参数列表的某个构造函数的明确调用,这让你可以在一个构造函数中调用另一个构造函数.

类的初始化顺序:
[list=1]
[*]静态变量
[*]静态初始化块
[*]变量
[*]初始化块
[*]构造器
[/list]
继承情况下:
[list=1]
[*]父类--静态变量
[*]父类--静态初始化块
[*]子类--静态变量
[*]子类--静态初始化块
[*]父类--变量
[*]父类--初始化块
[*]父类--构造器
[*]子类--变量
[*]子类--初始化块
[*]子类--构造器
[/list]

静态方法或变量用类名直接调用,也可以用new出来的对象调用;
无论是用类名调用还是用对象调用静态方法,都不可访问非静态成员变量和方法[color=red](TIJ中的注释中写道:使用对象调用静态方法可以访问非静态成员变量和方法.但实验后发现不行)[/color]如下代码所示
public class Test {

int i = 0;
static int test1(int a) {
return a+=2;
};
int test2() {
return 0;
};

public static void main (String args[]) {
Test test = new Test();
test.test1(i);//编译错误:Cannot make a static reference to the non-static field i
test.test1(test2());//编译错误:Cannot make a static reference to the non-static method test2() from the type Test
}
}


垃圾回收器的几种工作机制:
[list]
[*]Reference counting
[*]Mark-and-sweep
[*]Stop-and-copy
[/list]
可变参数列表:
在某些场合你的方法的参数个数或类型不确定,你可以使用"可变参数列表"
在SE5以前,你可以使用Object[] args来表示不确定的参数,但是在调用的时候你也需要将你的参数组合成一个Object数组,书中示例代码如下:
// Using array syntax to create variable argument lists.

class A {}

public class VarArgs {
static void printArray(Object[] args) {
for(Object obj : args)
System.out.print(obj + " ");
System.out.println();
}
public static void main(String[] args) {
printArray(new Object[]{
new Integer(47), new Float(3.14), new Double(11.11)
});
printArray(new Object[]{"one", "two", "three" });
printArray(new Object[]{new A(), new A(), new A()});
}
} /* Output: (Sample)
47 3.14 11.11
one two three
A@1a46e30 A@3e25a5 A@19821f
*///:~

在SE5中可以用Object... args来表示可变参数列表(Object可以置换为其他的引用类型或基本类型),同时在调用这个方法的时候用不需要再显式地将你的参数组合成一个数组,自动包装机制(AutoBoxing)在需要的时候也会自动的执行.书中示例代码如下:
// Using array syntax to create variable argument lists.

public class NewVarArgs {
static void printArray(Object... args) {
for(Object obj : args)
System.out.print(obj + " ");
System.out.println();
}
public static void main(String[] args) {
// Can take individual elements:
printArray(new Integer(47), new Float(3.14),
new Double(11.11));
printArray(47, 3.14F, 11.11);
printArray("one", "two", "three");
printArray(new A(), new A(), new A());
// Or an array:
printArray((Object[])new Integer[]{ 1, 2, 3, 4 });
printArray(); // Empty list is OK
}
} /* Output: (75% match)
47 3.14 11.11
47 3.14 11.11
one two three
A@1bab50a A@c3c749 A@150bd4d
1 2 3 4
*///:~

类似于printArray(Object... args)这样声明参数的方法接受空参数列表调用,例如printArray();所以当一系列的重载方法中包含拥有可变参数列表的方法时,很容易发生Method ambiguous的错误,所以在设计方法时要多加小心,经常的做法是在参数列表中增加一个非可变参数.

Eunmerated Types:
enum是SE5中新引入的关键字,用于声明枚举类型.枚举类型中的值一般使用大写表示,因为他们都是静态常量.
public enum Spiciness {
NOT, MILD, MEDIUM, HOT, FLAMING
} ///:~


一般情况下你可以把一个enum类型当成一个类来对待.它有几个有用的方法:
[list]
[*]static values():按声明的顺序返回一个包含enum常量的数组
[*]ordinal():返回enum实例所包含的常量在enum声明中的位置.
[*]toString();返回enum实例所包含的常量的名字.
[/list]此外,enum可以用在switch语句中,代表其包含的几种可能性.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值