java - 为什么必须在访问字段之前调用 super 构造函数?

标签 java bytecode

我的一个类继承 self 使用的框架中的一个类。父类(super class)在其构造函数中调用一个方法,我在自己的类中覆盖了该方法。 该方法使用了一个字段,我想在它被 super 构造函数调用之前 初始化以避免 NullPointerException。

有什么办法吗?

这是一个综合测试场景,我希望 Child 中的 c 在调用 call 时不为 null。

public class Test {

    public static class Parent {
        public Parent() {
            super();
            call();
        }

        // only called from parent constructor
        public void call() {
            System.out.println("Parent");
        }
    }

    public static class Child extends Parent {

        private Child c = this;

        public Child() {
            super();
        }

        // only called from parent constructor
        public void call() {
            System.out.println("Child, c is " + (c == null ? "null" : "this"));
        }
    }

    public static void main(String[] args) {
        new Child();
    }
}

在 Java 7 之前,这是可能的。我可以通过这样的特技来度过难关:

    public static class Child extends Parent {

        private Child c;

        private Child(Object unused) {
            super();
        }

        public Child() {
            this(c = this);
        }

        // only called from parent constructor
        public void call() {
            System.out.println("Child, c is " + (c == null ? "null" : "this"));
        }
    }

现在,这不再有效了。我很欣赏额外的安全性,但是 super 的调用破坏了它获得的任何安全性并降低了灵 active 。

我想要一种规避此限制的方法。 作为替代方案,我想知道避免 super 构造函数情况的限制会带来什么。

最佳答案

静态初始化器将在父类(super class)构造函数之前被调用。但是,您将无法设置任何非静态字段,因此它很可能无济于事。

http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html

非静态初始化 block 也无济于事,因为它是在父类(super class)构造函数完成后调用的。

另一种方法可能是在从 super 构造函数调用时什么也不做,然后再次调用子构造函数,例如:

    public Child() {
        super();
        call();
    }

    public void call() {

       if (c==null) {
         return;
       }

       System.out.println("do something with c now");

    }

如果在依赖于此方法的 super 构造函数中发生更多事情,这将不起作用。

我必须同意 EJP 的观点,这是个坏主意;找到一个不涉及折磨构造函数的完全不同的解决方案会好得多。

关于java - 为什么必须在访问字段之前调用 super 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20347704/

相关文章:

java - 整数不相加

java - 使用 SwingUtilities.invokeLater 专注于 JDialog?

java - 如何更改闭源类以操纵其中的方法

java - 二元运算符何时在 Java 中执行?

java - Java 字节码中的堆栈=4。 Java 编译器如何计算 4 值? (栈的深度)

jsp - 是否可以缓存 JSP 字节码以避免使用 Tomcat 重新编译?

java - 将 JSON 映射到列表<Map<<String, Object>>

java - 尝试播放音频,使我没有声音

java - 使用 BreakIterator 跳过非字母字符

java - 使用 ASM 库覆盖 Java 字节码中的局部变量名称