用构造器确保初始化:通过构造器,确保每个对象都被初始化。构造器名字与类名相同。在创建对象时分配空间,并调用相应的构造器完成初始化。在java中,初始化和创建是捆绑在一起的,不能分离。构造器是一种特殊的方法,没有返回值。
方法重载:方法名相同而形式参数不同,每个重载的方法靠形式参数列表来区分。当传入的实际参数类型小于形式参数类型,会自动转换,实际数据类型会提升(对于char类型,会转变为int类型)。如果传入的实际参数大于形式参数,需要进行显示窄化转换。
缺省构造器(缺省、无参):当写的类中没有构造器,编译器自动创建。若定义了有参构造器,则必须手动定义无参构造器。
this关键字:编译器暗自把“所操作对象的引用”作为第一个参数传给方法。假如希望在方法内部获得对正在调用该方法的当前对象的引用,就用this,this只能在方法内部使用。如果方法内需要调用同一个类的另一个方法,不需要this,可直接调用。
this还可以在构造其中调用构造器。一个构造器只能调用一个其他构造器,且要放在最开始,否则报错。只能在构造器内调用,不得在其他地方用this调用构造器。
由this可理解static,在static方法内部不能调用非static方法,反过来却可以。一般static直接用类调用,不需要创建对象。在类中置入static方法就可以访问其他static方法和static域。
//调用类内其他方法可不用this public class Apricot{ void pick(){......} void pit(){pick();......) } //用this表示对当前对象的引用 public class Leaf{ int i=0; Leaf increment(){ i++; return this; } void print(){System.out.println("i="+i);} public static void main(String[] args){ Leaf x=new Leaf(); x.increment().increment().increment().print(); //i=3 } } //this将当前对象传递给其他方法 class Person { public void eat(Apple apple) { Apple peeled=apple.getPeeled(); System.out.print("Yummy"); } } class Peeler { static Apple peel(Apple apple) { //remove peel return apple; //peeled } } class Apple { Apple getPeeled() { return Peeler.peel(this);//用this将自身传递给外部方法 } } public class PassingThis { public static void main(String[] args) { // TODO Auto-generated method stub new Person().eat(new Apple()); }//Yummy }
//this调用构造器 import static net.mindview.util.Print.*; public class Flower { int petalCount=0; String s="initial value"; Flower(int petals){ petalCount=petals; print("Constructor w/ int arg only,petalCount= "+petalCount); } Flower(String ss){ print("Constructor w/ String arg only,s="+ss); s=ss; } Flower(String s,int petals){ this(petals);//只能调用一个,且要放在最开始 this.s=s; //前一个s是成员,后一个s是参数 print("String & int args"); } Flower(){ this("hi",47); print("default comstructor(no args)"); } void printPetalCount() { print("petalCount="+petalCount+"S="+s); } public static void main(String[] args) { Flower x=new Flower(); x.printPetalCount(); } }/*Output: Constructor w/ int arg only,petalCount= 47 String & int args default comstructor(no args) petalCount=47S=hi */
清理:终结处理和垃圾回收:对于不是new获得的特殊内存区域,由于垃圾回收器只回收new分配的内存,在这种情况下允许在类中定义finalize()方法来回收。finalize()先被调用,在下一次垃圾回收发生时,才会真正回收内存。常用finalize()来发现一些缺陷,以下示范一下。
对象可能不被垃圾回收;垃圾回收不等于“析构”;垃圾回收只与内存有关
class Book { boolean checkedOut=false; Book(boolean checkOut){ checkedOut=checkOut; } void checkIn() { checkedOut=false; } protected void finalize() { if(checkedOut) { System.out.print("Error:checked out"); } } } public class TerminationCondition { public static void main(String[] args) { // TODO Auto-generated method stub Book novel =new Book(true); //proper cleanup novel.checkIn(); //drop the reference,forget to clean up new Book(true); //force garbage collection&finalization System.gc(); //Error:checked out } }
本例终结条件是:所有book对象在被gc前都被checkIn,但由于疏忽有一个没有checkIn就回收了,所以会打印出error。用finalize()来验证这个终结条件。
成员初始化:方法里的局部变量一定要初始化,而类中的字段可以被默认初始化为0、null、false。
构造器初始化:静态初始化只在必要时刻进行,在第一次被创建的时候进行,不可以再次初始化。
对象创建过程:1查找类路径,定位.class文件
2载入.class,静态初始化
3当new对象的时候,在堆上为对象分配存储空间
4这块存储空间清零,自动将对象所有基本类型设置成默认值
5执行所有出现于field定义处的初始化动作
6执行构造器
//各种初始化发生的顺序(尤其注意静态初始化只执行一次)
//而实例初始化每次被调用都会执行
class Bowl { Bowl(int marker){ System.out.println("Bowl("+marker+")"); } void f1(int marker) { System.out.println("f1("+marker+")"); } } class Table { static Bowl bowl1=new Bowl(1);//----1 Table(){ //-----3 System.out.println("Table()"); bowl2.f1(1); } void f2(int marker) { System.out.println("f2("+marker+")"); } static Bowl bowl2=new Bowl(2);//-----2 } class Cupboard { Bowl bowl3=new Bowl(3); //------3 static Bowl bowl4=new Bowl(4);//------1 Cupboard(){ //------4 System.out.println("Cupboard()"); bowl4.f1(2); } static void f3(int marker) { System.out.println("f3("+marker+")"); } static Bowl bowl5=new Bowl(5);//-------2 } import static net.mindview.util.Print.*; public class StaticInitialization { public static void main(String[] args) { print("Creating new Cupboard() in main");//3 new Cupboard();//4,不再静态初始化 print("Creating new Cupboard() in main"); new Cupboard(); table.f2(1); Cupboard.f3(1); } static Table table= new Table();//1 static Cupboard cupboard=new Cupboard();//2 }/*output: Bowl(1) Bowl(2) Table() f1(1)- Bowl(4) Bowl(5) Bowl(3) Cupboard() f1(2) Creating new Cupboard() in main Bowl(3) Cupboard() f1(2) Creating new Cupboard() in main Bowl(3) Cupboard() f1(2) f2(1) f3(1) */
数组初始化:数组的赋值只是赋了数组的引用。数组有个length固定成员,不可修改。对于引用类型的数组,new之后还是个引用数组,直到创建新的对象并赋给引用,才算完成初始化过程。使用空引用会出错。
static void printArray(Object... args){ //可变参数列表
for(Object obj:args)
print(obj+" ";
println();
}