【问题标题】:Using getter/setter other than public field for binary compatibility?使用公共字段以外的 getter/setter 来实现二进制兼容性?
【发布时间】:2012-04-18 13:36:22
【问题描述】:

我正在阅读“实用 API 设计”并找到以下段落:

"在 JVM 规范中可以找到更喜欢方法而不是字段的另一个原因。您可以将方法从类移动到其超类之一,并且仍然保持二进制兼容性。因此,方法最初作为 Dimension javax.swing.JComponent.getPreferredSize(Dimension d) 引入的新版本可以删除并移至 Dimension java.awt.Component.getPreferredSize(Dimension d),因为 JComponent 是 Component 的子类。A这样的变化在JDK 1.2中确实发生过,之所以能做到,只是因为字段被方法封装了。这样的操作是不允许对字段进行的。一旦在类中定义了字段,它就必须永远留在那里保持二进制兼容性,这是保持字段私有的另一个原因

因为我同意使用 getter/setter 是更好的方法。但我不明白为什么将公共字段移动到父类会破坏二进制兼容性?只要它在父类中是公共的,您仍然应该能够通过子类访问该字段。

【问题讨论】:

    标签: java getter-setter binary-compatibility


    【解决方案1】:

    一旦在类中定义了一个字段,它就必须永远留在那里以保持二进制兼容性

    这将是非常令人惊讶的:

    Java 语言规范,Java SE 7 版,defines 非限定字段访问表达式的二进制名称如下:

    给定一个表示类 C 中的字段访问的合法表达式,引用在(可能不同的)类或接口 D 中声明的名为 f 的非常量(第 13.4.9 节)字段,我们定义该字段的限定类型参考如下:

    • 如果表达式的格式为 Primary.f,则:
      • 如果 Primary 的编译时类型是交集类型 (§4.9) V1 & ... & Vn,则引用的限定类型为 V1。
      • 否则,Primary 的编译时类型是引用的限定类型。

    (Java 1.5 的语言规范uses 完全相同的措辞)

    也就是说,字段访问表达式的二进制名称不涉及声明该字段的类型,仅涉及我们用于访问该字段的主表达式的类型,因此无论该类型的哪个超类声明该字段,编译器需要相同字段引用发送到类文件中。

    确实,当我刚刚尝试从

    package p;
    
    public class Super {
    
    }
    
    package p;
    
    public class Sub extends Super {
        public String message;
    
        @Override
        public String toString() {
            return message;
        }
    }
    

    package p;
    
    public class Super {
        public String message;
    }
    
    package p;
    
    public class Sub extends Super {
        @Override
        public String toString() {
            return message;
        }
    }
    

    无需重新编译

    package p;
    
    public class Main {
        public static void main(String[] args) {
            Sub sub = new Sub();
            sub.message = "hello";
            System.out.println(sub);
            System.out.println(sub.message);
        }
    }
    

    我仍然收到了

    的输出
    hello
    hello
    

    ,不是LinkageError

    总而言之,这种说法对于 Java 7 是不正确的。对于 JDK 1.4 或更早版本可能是正确的,因为 JDK 1.4 或更早版本在 5 年多前被宣布终止生命周期。无论哪种方式,也许您应该使用更好/更新的书?

    【讨论】:

    • 这是我唯一能猜到的。也许在很老的时候,它是。
    【解决方案2】:

    如果我没记错的话,这本书解释了这一点,但我目前手头没有。我认为这是关于 Java 语言和类文件格式(Java 以外的其他语言也使用)之间的细微差别。

    在之前或之后检查一下这本书。询问您是否对该部分有更多问题。

    【讨论】:

    • 其实我是在完成那一章之后才提出这个问题的。我没有看到任何解释。尽管有一些关于热点 JVM 的故事,但我认为这部分不能回答我的问题
    猜你喜欢
    • 2010-09-11
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    相关资源
    最近更新 更多