美文网首页
《疯狂JAVA讲义》第四版 -> BUG

《疯狂JAVA讲义》第四版 -> BUG

作者: 蝉鸣的雨 | 来源:发表于2020-07-03 17:04 被阅读0次

    P159 第二个注意框里,有关代码块的描述如下:

    实际上初始化块是一个假象,使用 Javac 命令编译 Java 类后,该 Java 类中的初始化 一: 块会消失---初始化块中代码会被"还原"到每个构造器中,且位于构造器所有代码的 南 前面 。
    

    然后经过代码检验,发现此处的描述初始化块中代码会被"还原"到每个构造器中有误,测试代码如下:

    public class InitializeDemo {
    
        private String name;
        private int age;
    
        {
            this.name = "william";
            this.age = 10;
        }
    
        public InitializeDemo() {
        }
    
        public static void main(String[] args) {
            InitializeDemo demo = new InitializeDemo();
            System.out.println(demo.getName());
            System.out.println(demo.getAge());
        }
        // 省略getter setter
    }
    

    编译后的class文件中的代码经过反编译后,为

    public class InitializeDemo {
        private String name = "william";
        private int age = 10;
    
        public InitializeDemo() {
        }
    
        public static void main(String[] args) {
            InitializeDemo demo = new InitializeDemo();
            System.out.println(demo.getName());
            System.out.println(demo.getAge());
        }
        // 省略getter setter
    }
    

    发现编译后的代码块中的内容,并未还原到构造器中,而是添加到了成员变量中。

    那么,什么情况下,才会将代码块中的定义还原到构造器中呢?如下测试:

    public class InitializeDemo {
    
        private String name;
        private int age;
    
        {
            setName("william");
            setAge(10);
        }
    
        public InitializeDemo() {
        }
        // getter setter 等其他代码
    }
    

    此时编译后的class文件为:

    public class InitializeDemo {
        private String name;
        private int age;
    
        public InitializeDemo() {
            this.setName("william");
            this.setAge(10);
        }
    
        public static void main(String[] args) {
            InitializeDemo demo = new InitializeDemo();
            System.out.println(demo.getName());
            System.out.println(demo.getAge());
        }
        // getter setter 等其他代码
    }
    

    此时的变量初始化就被编译到了构造器中了。

    其原因可通过类初始化过程解释。但是书中并未指明这两种方式的区别,笼统的按第二种方式来解释,可见不太严谨。

    相关文章

      网友评论

          本文标题:《疯狂JAVA讲义》第四版 -> BUG

          本文链接:https://www.haomeiwen.com/subject/cznsqktx.html