使用除公共字段之外的getter/setter来实现二进制兼容性?

zx_*_*ing 5 java binary-compatibility getter-setter

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

" 可以在JVM规范中找到优先使用字段的方法的另一个原因.您可以将方法从类移动到其超类之一,并且仍然保持二进制兼容性.因此,最初作为Dimension javax.swing引入的方法.JComponent.getPreferredSize(Dimension d)可以在新版本中删除并移动到Dimension java.awt.Component.getPreferredSize(Dimension d),因为JComponent是Component的子类.这样的更改确实发生在JDK 1.2中,并且这可以仅仅因为字段被方法封装而完成.对于字段不允许这样的操作.一旦在类中定义字段,它必须永远保持在那里以保持二进制兼容性,这是另一个原因保持字段私密 "

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

mer*_*ike 3

\n

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

\n
\n

这将是非常令人惊讶的:

\n

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

\n
\n

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

\n
    \n
  • 如果表达式的形式为 Primary.f,则:\n
      \n
    • 如果 Primary 的编译时类型是交集类型 (\xc2\xa74.9) V1 & ... & Vn,则引用的限定类型为 V1。
    • \n
    • 否则,Primary 的编译时类型是引用的限定类型。
    • \n
    \n
  • \n
\n
\n

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

\n

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

\n

确实,当我刚才尝试从

\n
package p;\n\npublic class Super {\n\n}\n\npackage p;\n\npublic class Sub extends Super {\n    public String message;\n\n    @Override\n    public String toString() {\n        return message;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

\n
package p;\n\npublic class Super {\n    public String message;\n}\n\npackage p;\n\npublic class Sub extends Super {\n    @Override\n    public String toString() {\n        return message;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

无需重新编译

\n
package p;\n\npublic class Main {\n    public static void main(String[] args) {\n        Sub sub = new Sub();\n        sub.message = "hello";\n        System.out.println(sub);\n        System.out.println(sub.message);\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我仍然收到了输出

\n
hello\nhello\n
Run Code Online (Sandbox Code Playgroud)\n

,不是LinkageError

\n

总而言之,这种说法对于 Java 7 来说并不正确。对于 JDK 1.4 或更早版本可能是正确的,JDK 1.4 或更早版本在 5 年多前就被宣布终止生命。不管怎样,也许你应该使用一本更好/更新的书?

\n