求教静态初始化块、对象初始化块、构造器执行顺序问题

时间:2022-12-31 17:22:38
package kevin.study.CT;


public class ConstructorTest
{
public static void main(String[] args)
{

Employee[] staff=new Employee[3];
staff[0]=new Employee("Harry",4000);
System.out.println("Next availble Id is:"+Employee.getnextId());     staff[1]=new Employee(5000);
    staff[2]=new Employee();
     
   
    
     for(Employee e:staff)
     System.out.println("id:"+e.getId()+ ",name:"+e.getname()+ ",salary:"+e.getsalary());
    
}

}

import java.util.*;

class Employee 
{
public Employee(String n, double s)
   {
   name=n;
   salary=s;
   }
    
public Employee(double s)
{
this("Employee #"+nextId,s);
}
    
public Employee()
{

}

public String getname()
{
return name;
}

public double getsalary()
{
return salary;
}

public int getId()
{
return id;
}

public static int getnextId()
{
return nextId;
}

private String name="Hellen";
private double salary=6000;
private int id;
private static int nextId;

static
{
Random generator=new Random();
nextId=generator.nextInt(10000);
}

{
id=nextId;
nextId++;

}

}

今天看书看到有关初始化块的内容,然后根据书上的一个例子操作了一下。上面代码中红色的部分是想验证nextId的值在不同地方各是多少?结果发现nextId在生成随机数字后,把他放在STAFF这3个数组的不同地方,在控制台上输出的值也是不同的。虽然和我设想的一样,但是想不通的是nextId在系统内是如何变化(就是程序的执行顺序)的?他在什么时候会自加1,然后输出呢?
        求各位高人指教!!!

11 个解决方案

#1


非静态块在new对象的时候执行 你在非静态块里面加个输出看下就明白

#2


用了你的方法看了一下,确实是这样。创建了3个对象期间,执行了3次非静态块,得到3个ID。不过又有个问题就是:得到这3个ID后,它们在输出前是存放在哪里的?在调用GETID的时候从哪里取出这3个值输出的?

#3


每个对象在new的时候都会分配一块内存地址的~~所以每个对象都会有一个id互相没有关系的。你get的时候也是各自拿各自的。说到静态块,就像静态变量一样,是所有对象所共享的!

#4


static
{
Random generator=new Random();
nextId=generator.nextInt(10000);
}
这个东西是最先开始执行的,当虚拟机装载这个类的时候,这段代码就执行了,
对象初始化块先于构造函数执行。构造函数是最后执行的

#5


哦,可不可以这样理解。就是ID这个实例域本来就属于对象内的,在创建好3个对象并赋予3个数组后,把数组各自存储在不同内存单元,非静态块执行生成3个ID也放在了3个数组对应的内存中?

#6


引用 5 楼 kevinwxy 的回复:
哦,可不可以这样理解。就是ID这个实例域本来就属于对象内的,在创建好3个对象并赋予3个数组后,把数组各自存储在不同内存单元,非静态块执行生成3个ID也放在了3个数组对应的内存中?

差不多吧

#7


静态(方法、属性、变量)在类加载时执行,然后对象初始化,最后执行构造器给类成员赋值

#8


好的,谢谢啦~
引用 6 楼 tkd03072010 的回复:
引用 5 楼 kevinwxy 的回复:

哦,可不可以这样理解。就是ID这个实例域本来就属于对象内的,在创建好3个对象并赋予3个数组后,把数组各自存储在不同内存单元,非静态块执行生成3个ID也放在了3个数组对应的内存中?

差不多吧

#9


那MAIN方法下的这些语句是什么时候执行的啊?按1L的意思,感觉是在静态初始化块后,对象初始化前吗?
引用 7 楼 xifengwujiutian 的回复:
静态(方法、属性、变量)在类加载时执行,然后对象初始化,最后执行构造器给类成员赋值

#10


谢谢答复哈~小弟刚开始学JAVA,以后还有问题还请多指教啊!
引用 1 楼 zhouyuqwert 的回复:
非静态块在new对象的时候执行 你在非静态块里面加个输出看下就明白

#11


引用 9 楼 kevinwxy 的回复:
那MAIN方法下的这些语句是什么时候执行的啊?按1L的意思,感觉是在静态初始化块后,对象初始化前吗?引用 7 楼 xifengwujiutian 的回复:
静态(方法、属性、变量)在类加载时执行,然后对象初始化,最后执行构造器给类成员赋值

静态方法都需要调用才能执行的 不是加载就能执行的 方法跟块有区别的
静态块是在类加载时执行,静态方法需要调用才能执行,main方法只不过是被虚拟机调用了作为程序的入口

#1


非静态块在new对象的时候执行 你在非静态块里面加个输出看下就明白

#2


用了你的方法看了一下,确实是这样。创建了3个对象期间,执行了3次非静态块,得到3个ID。不过又有个问题就是:得到这3个ID后,它们在输出前是存放在哪里的?在调用GETID的时候从哪里取出这3个值输出的?

#3


每个对象在new的时候都会分配一块内存地址的~~所以每个对象都会有一个id互相没有关系的。你get的时候也是各自拿各自的。说到静态块,就像静态变量一样,是所有对象所共享的!

#4


static
{
Random generator=new Random();
nextId=generator.nextInt(10000);
}
这个东西是最先开始执行的,当虚拟机装载这个类的时候,这段代码就执行了,
对象初始化块先于构造函数执行。构造函数是最后执行的

#5


哦,可不可以这样理解。就是ID这个实例域本来就属于对象内的,在创建好3个对象并赋予3个数组后,把数组各自存储在不同内存单元,非静态块执行生成3个ID也放在了3个数组对应的内存中?

#6


引用 5 楼 kevinwxy 的回复:
哦,可不可以这样理解。就是ID这个实例域本来就属于对象内的,在创建好3个对象并赋予3个数组后,把数组各自存储在不同内存单元,非静态块执行生成3个ID也放在了3个数组对应的内存中?

差不多吧

#7


静态(方法、属性、变量)在类加载时执行,然后对象初始化,最后执行构造器给类成员赋值

#8


好的,谢谢啦~
引用 6 楼 tkd03072010 的回复:
引用 5 楼 kevinwxy 的回复:

哦,可不可以这样理解。就是ID这个实例域本来就属于对象内的,在创建好3个对象并赋予3个数组后,把数组各自存储在不同内存单元,非静态块执行生成3个ID也放在了3个数组对应的内存中?

差不多吧

#9


那MAIN方法下的这些语句是什么时候执行的啊?按1L的意思,感觉是在静态初始化块后,对象初始化前吗?
引用 7 楼 xifengwujiutian 的回复:
静态(方法、属性、变量)在类加载时执行,然后对象初始化,最后执行构造器给类成员赋值

#10


谢谢答复哈~小弟刚开始学JAVA,以后还有问题还请多指教啊!
引用 1 楼 zhouyuqwert 的回复:
非静态块在new对象的时候执行 你在非静态块里面加个输出看下就明白

#11


引用 9 楼 kevinwxy 的回复:
那MAIN方法下的这些语句是什么时候执行的啊?按1L的意思,感觉是在静态初始化块后,对象初始化前吗?引用 7 楼 xifengwujiutian 的回复:
静态(方法、属性、变量)在类加载时执行,然后对象初始化,最后执行构造器给类成员赋值

静态方法都需要调用才能执行的 不是加载就能执行的 方法跟块有区别的
静态块是在类加载时执行,静态方法需要调用才能执行,main方法只不过是被虚拟机调用了作为程序的入口