自动初始化(默认值)
一个类的所有基本数据成员都会得到初始化,运行下面的例子可以查看这些默认值:
class Default{
? ? boolean t;
? ? char c;
? ? byte b;
? ? short s;
? ? int i;
? ? long l;
? ? float f;
? ? double d;
? ? public void show() {
? ? ? ? System.out.println("基本类型? 初始化值\n"+
? ? ? ? ? ? ? ? ? ? ? ? "boolean<----->" + t +"\n" +
? ? ? ? ? ? ? ? ? ? ? ? "char<----->" + c +"\n" +
? ? ? ? ? ? ? ? ? ? ? ? "byte<----->" + b + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "short<----->" + s + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "int<----->" + i + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "long<----->" + l + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "float<----->" + f + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "double<----->" + d + "\n"
? ? ? ? );
? ? }
}
public class InitValue {
? ? public static void main(String[] args) {
? ? ? ? Default d = new Default();
? ? ? ? d.show();
? ? }
}
【运行结果】:
基本类型? 初始化值
boolean<----->false
char<----->
byte<----->0
short<----->0
int<----->0
long<----->0
float<----->0.0
double<----->0.0
其中,char类型的默认值为空(null)。
对于非基本数据类型而言,对象的句柄也会被初始化:
class Person {
? ? private String name;
? ? // setter
}
class Default {
? ? Person p;
? ? public void show() {
? ? ? ? System.out.println("Person<----->" + p);
? ? }
}
public class InitValue {
? ? public static void main(String[] args) {
? ? ? ? Default d = new Default();
? ? ? ? d.show();
? ? }
}
【运行结果】:
Person<----->null
可见,句柄初始化值为null。这就是说,如果没有为p指定初始化值就调用类似于p.setName的方法,就会出现异常。
规定初始化
如果需要自己为变量赋一个初始值,可以在定义变量的同时赋值。
class Default{
? ? boolean t = true;
? ? char c = 'A';
? ? byte b = 47;
? ? short s = 0xff;
? ? int i = 24;
? ? long l = 999;
? ? float f = 1.2f;
? ? double d = 1.732;
? ? public void show() {
? ? ? ? System.out.println(
? ? ? ? ? ? ? ? ? ? ? ? "boolean<----->" + t +"\n" +
? ? ? ? ? ? ? ? ? ? ? ? "char<----->" + c +"\n" +
? ? ? ? ? ? ? ? ? ? ? ? "byte<----->" + b + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "short<----->" + s + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "int<----->" + i + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "long<----->" + l + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "float<----->" + f + "\n" +
? ? ? ? ? ? ? ? ? ? ? ? "double<----->" + d + "\n"
? ? ? ? );
? ? }
}
public class InitValue {
? ? public static void main(String[] args) {
? ? ? ? Default d = new Default();
? ? ? ? d.show();
? ? }
}
甚至可以通过一个方法来进行初始化;
class Person {
? ? int i = set();
? ? //...
}
这些方法也可以使用自变量:
class Person {
? ? int i;
? ? int j = set(i);
? ? //...
}
构建器初始化
构建器进行初始化的优点是可以在运行期决定初始化值。例如:
class Person {
? ? int age;
? ? Person() {
? ? ? ? age = 89;
? ? }
}
age首先会初始化为0,然后变成89。对于所有基本类型以及对象的句柄,这种情况都是成立的。
初始化顺序
在一个类里,初始化的顺序是由变量在类内的定义顺序决定的。即使变量定义大量遍布于方法定义的中间,那么变量仍然会在调用任何方法(包括构造函数)之前得到初始化。例如:
class Pet {
? ? Pet(int age) {
? ? ? ? System.out.println("Pet(" + age + ")");
? ? }
}
class Person {
? ? Pet t1 = new Pet(1);
? ? Person() {
? ? ? ? System.out.println("---Person()---");
? ? ? ? t3 = new Pet(33);
? ? }
? ? Pet t2 = new Pet(2);
? ? void show() {
? ? ? ? System.out.println("show----running");
? ? }
? ? Pet t3 = new Pet(3);
}
public class OrderOfInitialization {
? ? public static void main(String[] args) {
? ? ? ? Person p = new Person();
? ? ? ? p.show();
? ? }
}
【运行结果】:
Pet(1)
Pet(2)
Pet(3)
---Person()---
Pet(33)
show----running
上例中,虽然t1、t2、t3的定义遍布于类中,但是初始化的先后顺序是由t1、t2、t3的定义顺序决定的(自己动手调换t1、t2、t3看看结果),且初始化优先于构建器执行,当调用Person的构建器时,t3重新初始化。
静态数据的初始化
如果数据是静态的(static),同样的过程也会执行。若属于基本类型,而且未对其进行初始化,就会自动获得自己的标准基本类型初始值;若它是指向一个对象的句柄,除非创建一个对象同它连接起来,否则得到一个空值(null)。如果在定义时初始化,采取的方式与非静态值是不同的,这是因为static只有一个存储区域。例如:
class Bowl {
? ? Bowl(int marker) {
? ? ? ? System.out.println("Bowl(" + marker + ")");
? ? }
? ? void f(int marker) {
? ? ? ? System.out.println("f(" + marker + ")");
? ? }
}
class Table {
? ? static Bowl b1 = new Bowl(1);
? ? Table() {
? ? ? ? System.out.println("Table()");
? ? ? ? b2.f(1);
? ? }
? ? void f2(int marker) {
? ? ? ? System.out.println("f2(" + marker + ")");
? ? }
? ? static Bowl b2 = new Bowl(2);
}
class Cupboard {
? ? Bowl b3 = new Bowl(3);
? ? static Bowl b4 = new Bowl(4);
? ? Cupboard() {
? ? ? ? System.out.println("Cupboard()");
? ? ? ? b4.f(2);
? ? }
? ? void f3 (int marker) {
? ? ? ? System.out.println("f3(" + marker + ")");
? ? }
? ? static Bowl b5 = new Bowl