java中成员的初始化(java编程思想摘要)

1.和c中不同的是,在c语言中允许

    int i;
    printf("%d",i++);

这样使用,尽管这样是不正确的,没有对i值进行初始化。

在Java中,会强制要求程序员为i赋一个值,这样会让程序员更容易找出程序中的错误。

2.但是并不是在所有情况下,java都会这样要求我们,java会为类的每个基础类型成员赋一个初始值。

 

新建这样一个测试类,然后在main中调用这个类中的方法,打印出所有未经初始化(这里指我们没有进行初始化)基础类型成员的值。

public class InitialValues {
    boolean t;
    char c;
    byte b;
    int i;
    long l;
    float f;
    double d;
    InitialValues initialValues;
    public void printInitialValues(){
        System.out.println("boolean         "+t);
        System.out.println("char        [" +c+"]");
        System.out.println("byte        " +b);
        System.out.println("int     " +i);
        System.out.println("long        " +l);
        System.out.println("float       "+f);
        System.out.println("double      "+d);
        System.out.println("InitialValues       "+initialValues);
    }
public class Main {

    public static void main(String[] args) {
	   new InitialValues().printInitialValues();
    }
}

可以得到这样的结果,可以看到并没有报错,而且都被赋予了初始值,在类中定义一个对象引用,如果不将它初始化,此引用就会获得一个null值:

boolean         false

char        [ ]

byte        0

int     0

long        0

float       0.0

double      0.0

InitialValues       null

 

3.初始化的顺序

在java类中,尽管让变量定义散布在方法定义之间,变量定义还是会优先于方法定义(包括构造器方法)被执行

public class Window {
    Window(int marker){
        System.out.println("Window(" + marker +")");
    }
public class House {
    Window w1 = new Window(1);
    House(){
        System.out.println("House()");
        w3 = new Window(33);
    }
    Window w2 = new Window(2);
    void f(){
        System.out.println("f()");
    }
    Window w3 = new Window(3);
}
public class Main {

    public static void main(String[] args) {
	   new House().f();
    }
}

结果:

Window(1)

Window(2)

Window(3)

House()

Window(33)

f()

 

在House类中,我们让Window对象的定义散布在各处,证明他们全都会在构造器或其他方法调用之前得到初始化。

 

4.静态数据的初始化

无论创建多少个对象,静态数据都只占用一份存储区域。static关键字不能应用于局部变量,因此它只能作用于域。

public class Bowl {
    Bowl(int marker){
        System.out.println("Bowl(" + marker +")");
    }
    void f1(int marker){
        System.out.println("f1("+marker+")");
    }
}
public class Table {
    static Bowl bowl = new Bowl(1);
    Table(){
        System.out.println("Table()");
        bowl2.f1(1);
    }
    void f2(int marker){
        System.out.println("f2(" + marker + ")");
    }
    Bowl bowl2 = new Bowl(2);
}

 

public class Cupboard {
    Bowl bow3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);
    Cupboard(){
        System.out.println("Cupboard()");
        bowl4.f1(2);
    }
    void f3(int marker){
        System.out.println("f3(" + marker + ")");
    }
    static Bowl bowl5 = new Bowl(5);
}
public class Main {

    public static void main(String[] args) {
	// write your code here
     //   new InitialValues().printInitialValues();
     //   new House().f();

        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        System.out.println("Creating new Cupboard() in main");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
    }
    static Table table = new Table();
    static  Cupboard cupboard = new Cupboard();
}

结果:

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)

 

    静态初始化只有在必要的时刻才会进行,如果不创建Table 对象,也不引用Table.b1或Table.b2,那么静态的Bow1 b1和b2永远都不会被创建。只有在第一个Table对象被创建(或者第一次访问静态数据)的时候,它们才会被初始化。此后,静态对象不会再次被初始化。

    初始化的顺序是先静态对象,而后是“非静态”对象,在结果中标紫的地方可以看到。

 

总结一下对象的创建过程,假设有个名为Dog的类:

1.即使没有显示地使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时(构造器可以看成静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。

2.然后载入Dog.class,有关静态初始化的所有动作都会执行。因此,静态初始化只在Class对象首次加载的时候进行一次。

3.当用new Dog()创建对象的时候,首先将在堆上为Dog对象分配足够的存储空间。

4.这块存储空间会被清零,这就自动地将Dog对象中的所有基本类型数据都设置成了默认值。

5.执行所有出现于字段定义处的初始化动作。

6.执行构造器。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值