初始化与清理
1. 构造器中的this关键字
可能为一个类写了多个构造器,有时想在一个构造器中调用另一个构造器,以免重复代码,可以使用this关键字实现。
for example
public class ConstructorsWithThis {
private int petalCount=0;
private String s ="initial value";
ConstructorsWithThis(int petals){
petalCount = petals;
System.out.println("Constructor int arg only,petalCount= "+petalCount );
}
ConstructorsWithThis(String ss){
System.out.println("Constructor int arg only,s= "+ss );
s=ss;
}
ConstructorsWithThis(String s,int petals){
this(petals);
//this(s);
this.s = s;
System.out.println("String & int args");
}
ConstructorsWithThis(){
this("hello",66);
System.out.println("default constructor (no args)");
}
public void printPetalCount() {
System.out.println("petalCount= "+petalCount+" s= "+s);
}
public static void main(String[] args) {
ConstructorsWithThis constructorsWithThis = new ConstructorsWithThis();
constructorsWithThis.printPetalCount();
}
}
result
Constructor int arg only,petalCount= 66
String & int args
default constructor (no args)
petalCount= 66 s= hello
说明:
(1)ConstructorsWithThis(String s,int petals)表明:尽管可以使用this调用一个构造器,但是不能同时调用两个。
(2)除了构造器外禁止在其他任何方法中调用构造器。
2. static的含义
在static方法的内部不能调用非静态的方法,反过来倒是可以。
定义为static的东西只会被初始化一次。
在没有创建任何对象的前提下,可以通过类本省调用static方法。这就像全局方法。
3. 终结处理和垃圾回收
由于垃圾回收机制只知道回收释放哪些经由new分配的内存,假如对象没有通过new获得了一块特殊的内存,这时垃圾回收机制就不知怎么去回收这部分特殊的内存。为了因对这种特殊的情况java允许在类中定义一个名为finalize()的方法。
finalize()的工作原理是:一旦垃圾回收器准备好释放对象占用的内存空间时,将首相调用finalize()方法,并在下一次垃圾回收动作发生时,才会正真回收对象占用的内存。
垃圾回收的三点:
- 对象可能不被垃圾回收
- 垃圾回收并不等于“析构”
- 垃圾回收只与内存有关
finalize的用途
上面说到,finalize是作用与特殊情况,但是Java中一切皆对象,那么这种特殊情况又指的是什么呢?
看来之所以要用finalize是由于在分配内存时可能采取了类似于C语言的做法(malloc),而非java的方式。
4. 静态数据的初始化
无论创建多少个对象,静态数据都只占用一份存储空间。static关键字不能应用于局部变量,它只能作用于域。如果一个域是静态的基本类型域,且没有对他进行初始化,那么它就会获得基本类型的标准初始值(对于数字,布尔型,字符型 都是0;对于应用则是null)。
4.1 显示的静态初始化
public class Spoon{
static int i;
static{
i = 66;
}
}
跟在static关键字后面的代码只执行一次,当首次生成这个类的对象时,或者首次访问属于哪个类的静态数据成员时(即使从未生成过那个类的对象)。
4.2 非静态实例初始化
for example
public class message {
private String author;
private String content ;
{
author = "XXX";
content = "XXXXXXXX";
System.out.println("author & content initialized");
}
message(){
System.out.println("message()");
}
message(String author){
this.author = author;
System.out.println("message(String)");
}
@Override
public String toString() {
return "message [author=" + author + ", content=" + content + "]";
}
public static void main(String[] args) {
message m1 = new message();
System.out.println(m1.toString());
message m2 = new message("duqingqing0110");
System.out.println(m2.toString());
}
}
result
author & content initialized
message()
message [author=XXX, content=XXXXXXXX]
author & content initialized
message(String)
message [author=duqingqing0110, content=XXXXXXXX]
看起来它与静态初始化句子一模一样,只不过少了static关键字。这种语法对于支持匿名内部类的初始化是必须的。
5. 数组的初始化
花括号括起来的列表初始化对象数组,有两种形式:
public class ArrayInitialization {
public static void main(String[] args) {
Integer[] a = { new Integer(1), new Integer(2), 3, };
Integer[] b = new Integer[] { new Integer(1), new Integer(2), 3, };
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
}
}
/**
* 这两种形式中初始化列表的最后一个逗号都是可选的(这一特性使维护长列表变得更容易)
*/
[1, 2, 3]
[1, 2, 3]
5.1 可变参数列表
有了可变参,就再也不用显示的写数组的语法了,当你指定参数时编译器实际上会为你填充参数
for example
public class VariableParameterList {
public static void printArray(Object ... args) {
for(Object obj : args) {
System.out.print(obj+" ");
}
System.out.println();
}
public static void main(String[] args) {
printArray(new Integer(47),new Float(3.14),new Double(1024.001));
printArray("one","two");
printArray((Object[])new Integer[] {1,2,3,4,5,6});
}
}
result
47 3.14 1024.001
one two
1 2 3 4 5 6
6.枚举类型
Java SE5引入新关键字enum。下面列举中国市场的货币面额。
public enum Money {
ONE,FIVE,TEN,TWENTY,FIFTY,HUNDRED
}
在创建enum的时候,编译器会自动添加一些有用的特性。例如:
- toString()方法,以便直接打印enum的实例名字。
- ordinal()方法,用来表示某个特定的enum的声明顺序。
- static values()方法,用来按照enum的声名顺序,放回enum数组。
public class EnumTest {
public static void main(String[] args) {
for(Money m : Money.values()) {
System.out.println(m+",Ordinal="+m.ordinal());
}
}
}
ONE,Ordinal=0
FIVE,Ordinal=1
TEN,Ordinal=2
TWENTY,Ordinal=3
FIFTY,Ordinal=4
HUNDRED,Ordinal=5