大可制作:QQ群:31564239(asp|jsp|php|mysql)

Java Gossip: 构造方法(Constructor)

在定义类时,您可以使用“构造方法”(Constructor)来进行对象的初始化,而在Java中并没有 “解构方法”(Destructor),而是利用finalize()函数来达到解构方法的作用,这则在 垃圾回收 讨论。

在Java中构造方法是与类名称相同的公开方法成员,且没有传回值,例如:
public class SafeArray {
    // ..
 
    public SafeArray() {  // 构造方法
        // ....
    }
 
    public SafeArray(参数) {  //
        // ....
    }
}

在构造方法中,您可以定义无参数的构造方法,或具有参数的构造方法,程序在运行时,会根据配置对象时所指定的参数数据类型等来决定,该使用哪一个构造方法。

下面这个程序中,您实现“安全的数组”,使用我们所定义的数组类可以动态配置数组长度,并可事先检查存取数组的索引是否超出数组长度,在这个数组类中,您实现了几个简单的功能,像是传回数组长度、设定数组元素值、取得数组元素值等等,我们的类定义如下:

  • SafeArray.java
public class SafeArray { 
private int[] arr;

public SafeArray() {
this(10);
}

public SafeArray(int length) {
arr = new int[length];
}

public int[] getArray() {
return arr;
}

public int getElement(int i) {
if(i >= arr.length || i < 0) {
System.err.println("索引错误");
return 0;
}

return arr[i];
}

public int getLength() {
return arr.length;
}

public void setElement(int i, int data) {
if(i >= arr.length || i < 0) {
System.err.println("索引错误");
return;
}

arr[i] = data;
}
}

构造方法中,如果不指定参数的话,就会默认配置10个元素的数组,您也可以由指定的长度来配置数组;您在无参数的构造方法中直接使用this() 来调用另一个有参数的构造方法,这是一种经常的作法,可以避免撰写一些重覆的原始码。

下面这个程序示范如何使用自订的安全数组类:

  • UseConstructor.java
 
public class UseConstructor {
public static void main(String[] args) {
// 默认10个元素
SafeArray arr1 = new SafeArray();
// 指定配置20个元素
SafeArray arr2 = new SafeArray(20);

for(int i = 0; i < arr1.getLength(); i++)
arr1.setElement(i, (i+1)*10);

for(int i = 0; i < arr2.getLength(); i++)
arr2.setElement(i, (i+1)*10);

for(int element : arr1.getArray())
System.out.print(element + " ");
System.out.println();

for(int element : arr2.getArray())
System.out.print(element + " ");
System.out.println();
}
}


上面的程序中,您配置了两个SafeArray对象,一个使用默认的构造方法,所以arr1的数组元素会有10个,一个使用指定长度的构造方法,所以arr2的数组元素个 数是我们指定的20,构造方法依参数不同而自行决定该使用哪一个构造方法。

对象在建构之前,对象的属性必须先初始完毕才会执行建构式,例如:
public class Some {
    private Other other = new Other();

    public Some() {
         System.out.println("Some");
    }
}

public class Other {
    public Other() {
        System.out.println("Other");
    }
}

如果建构Some:
Some some = new Some();

由于先初始Some的属性成员,所以会先显示"Other",再显示"Some"。

如果您如下撰写:
public class Test {
    {
        System.out.println("initial...");
    }

    public Test() {
        System.out.println("Test");
    }

    public Test(int i) {
        System.out.println("Test i");
    }

    public static void main(String[] args) {
        new Test();
        new Test(1);
    }
}

在 { 与 } 之间的程序,会自动加入所有的构造函数开头,所以程序将显示:

initial...
Test
initial...
Test i