zoukankan      html  css  js  c++  java
  • 成员变量赋值问题【向前引用】

    今天,同学问了我一个问题,代码如下

    
    public class Test10 {
    
        //这个小程序 为啥不报错,应该是先执行a=10这个程序块,但是我们没有设定a的类型啊
        {
            a = 10;
        }
    
        int a = 20;
    
    
        public static void main(String[] args) {
            Test10 t = new Test10();
            System.out.println("a的数值为:" + t.a);
        }
    }
    
    
    • 开始的时候,我看到这个代码有点懵了(卧槽,谁会这样用啊),于是我就在想:为什么不报错,是不是JVM会把代码全都编译一次,执行到构造代码块的时候,发现后面有对a变量进行定义,所以没有报错。于是就上网查资料去了,后来发现java支持向前引用
    • 接着,我发现输出的值是20(卧槽,怎么是20???,不应该是a=10构造代码块覆盖了在定义成员变量时a=20吗)
    • 于是乎,我又作死地加入了一个构造函数进去,看看执行顺序到底是怎么样的
    
    public class Test10 {
    
    
        public Test10() {
    
            a=30;
        }
    
        //这个小程序 为啥不报错,应该是先执行a=10这个程序块,但是我们没有设定a的类型啊
        {
            a = 10;
        }
    
        int a = 20;
    
    
        public static void main(String[] args) {
            Test10 t = new Test10();
            System.out.println("a的数值为:" + t.a);
        }
    }
    
    
    • 因为java支持向前引用,构造函数的a那当然不会报错啦。我再次执行该测试的时候,发现a的值为30,此时又懵逼了。按我当时理解是这样的(既然上面输出的是20,那么我加入构造方法,构造方法在构造代码块后执行,同样会被a=20覆盖掉【当时候脑袋短路了,忘记构造方法会覆盖掉成员变量的值】
    • 最后我在知乎RednaxelaFX—-R大中一个回答中似乎找到了答案。截图如下:

    • 简要提炼下语句:对JVM来说所有实例初始化动作都要收集到“特殊的实例初始化方法”(名为“init”,内容对应所有实例初始化器+构造器)里,按代码顺序把实例初始化动作(包括实例字段初始化与匿名的实例初始化器)收集起来,然后是构造器自身的内容
    • 就是说构造代码块和成员变量的赋值顺序是依照代码的顺序执行的
    • 剔除构造方法,将构造代码块和声明成员变量位置交换一下,看看结果
    
    public class Test10 {
    
    
        int a = 20;
    
        {
            a = 10;
        }
    
    
        public static void main(String[] args) {
            Test10 t = new Test10();
            System.out.println("a的数值为:" + t.a);
        }
    }
    
    
    • 输出的结果是10。

    • ps:如果我有理解错误的地方,请留言,谢谢!

    参考资料:

    向前引用:http://www.cnblogs.com/nokiaguy/p/3156357.html

    执行顺序RednaxelaFX的回答:https://www.zhihu.com/question/36643366?q=java%E6%88%90%E5%91%98%E5%8F%98%E9%87%8F%E5%88%B0%E5%BA%95%E4%BB%80%E4%B9%88%E6%97%B6%E5%80%99%E8%A2%AB%E8%B5%8B%E5%80%BC%EF%BC%9F

    如果您觉得这篇文章帮助到了您,可以给作者一点鼓励



  • 相关阅读:
    数据仓库深入了解
    修改hive 默认fs为s3 遇到的坑
    Hadoop集群的各部分常用端口
    mvc结合web应用实例分析
    MVC简介
    关于jQuery获得表单radio类型输入框的选中值
    关于js中的取值问题
    struct2的xml文件中result的配置(转)
    关于http响应状态码
    关于hibernate插入数据到mysql数据库中文乱码问题的解决
  • 原文地址:https://www.cnblogs.com/zhong-fucheng/p/7203057.html
Copyright © 2011-2022 走看看