黑马程序员技术交流社区

标题: 关于类的初始化先后顺序 [打印本页]

作者: 石头135    时间: 2013-5-12 20:38
标题: 关于类的初始化先后顺序
本帖最后由 石头135 于 2013-5-14 12:40 编辑

在验证类的初始化先后顺序时,遇到一个问题,望大家指导!
class Person
{
        //显示初始化
                 String name="王二";     //位置1
        
        //构造代码块
        {
        System.out.println(name);
                 name ="zhangsan";
        System.out.println(name);
        }
               
        String name="王二";    //位置2
        
}

显示初始化不是在构造代码块之前执行吗?为什么我放在位置2(即在构造代码块之后)会报错"非法前向引用",而放在位置1(构造代码块之前)就OK?
作者: nihaoshitou    时间: 2013-5-12 20:50
1.一个对象第一次被创建时,先要加载该对象所属的类,即对应的.class文件,
当然如果类已经加载,再次创建该类的对象时,就不再需要重新加载类了。 而
一个类加载的时候,有三个部分需要加载:
a:一个是静态变量,
b:再然后是静态方法,
c:然后是静态初始化块。  
2. 然后开始创建该类的实例了,当然如果静态方法跟静态初始化对象中有对
象的创建时,就继续加载该对象的类,当然已经加载了该对象的类的话就不需
要再次加载了。
那么对象实例的创建过程是什么呢?
Java数据结构快速入门
Java数据结构基...Java数据结构基...
a:首先是成员变量的引入,
b:然后是实例初始化块,
c:之后才是构造方法,  
构造方法执行完成之后才算把这个对象给创建出来了。
显示初始化时优先于构造代码块执行的,如果构造代码初始化在显示初始化之前,
会导致报“非法前向引用”。
作者: 张迁    时间: 2013-5-12 20:54
构造块优先于构造方法运行,并且每一次实例化对象都会运行一次。
你的代码中,构造块先运行,找不到定义的 name,自然会报错。
作者: 赵利斌    时间: 2013-5-12 20:56
这样来验证:是在new 对象的时候  不是直接在main 函数里面验证
代码:

class Demo
{
        public static void main(String[] agrs)
        {
                Tex t=new Tex();
                System.out.print(t.name);
        }   
}
class  Tex
{
        //String name="王二";     //位置1
   
    //构造代码块
     {
     System.out.println(this.name);
     name ="zhangsan";
     System.out.println(this.name);
     }
            
    String name="王二";           //位置2
}
作者: 任江峰    时间: 2013-5-12 22:15
我在cmd下都能编译通过,并且正常运行。
从结果看出,成员变量的初始化时间跟放的位置有关:
String name="王二"; 放在构造代码块前面(位置1),就比构造代码块先执行。
String name="王二"; 放在构造代码块后面(位置2),就比构造代码块后执行。

1.jpg (50.99 KB, 下载次数: 0)

位置1

位置1

2.jpg (50.38 KB, 下载次数: 0)

位置2

位置2

作者: 袁术森    时间: 2013-5-13 14:40
我记得毕老师的视频里讲解过 一个类文件加载进内存的步骤   里面有静态代码块 构造代码块 局部代码块 等等
作者: 逝者轨迹    时间: 2013-5-13 17:43
String name="王二"; 在位置2的时候,先执行构造代码块,而此时name对象尚未被创建,

作者: 石头135    时间: 2013-5-13 21:43
1.
class Person
{
        Person()              //构造代码块初始化
        {
        System.out.println("显示初始化:"+name);
        name ="张三";
        System.out.println("构造代码块初始化:"+name);
        }
        String name="王二";   //显示初始化
}
class Demo
{
        public static void main(String[] args)
        {
                Person p =new Person();
        }
}



2.class Person
{
        String name="王二";   //显示初始化
        Person()              //构造代码块初始化
        {
        System.out.println("显示初始化:"+name);
        name ="张三";
        System.out.println("构造代码块初始化:"+name);
        }
       
}
class Demo
{
        public static void main(String[] args)
        {
                Person p =new Person();
        }
}

上面代码1.2两个代码都是显示初始化先执行,构造代码块后执行!!!
本来想附图片的,不知道咋弄,想验证结果的,自己编译下!!!
作者: 曹睿翔    时间: 2013-5-13 23:16

如果帖子没有问题了  那么把帖子的类型改为 “已解决”,  如果不会改   点自己的帖子下面有个编辑,然后改帖子的类型就好了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2