Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4354400

JLS-2: contradiction between rule in 13.1 and examples in 13.4.7



    • generic
    • generic


      Name: inR10064 Date: 07/19/2000

      A rule in 13.1 for qualifying type of field reference was changed in JLS-2
      compared with JLS-1 but corresponding example in 13.4.7 stays unchanged
      and contradicts the rule. There are two similar examples of such class
      change in 13.4.7 of JLS-2.

      Explanation of the example in 13.4.7 ( see below ) says that adding field h
      to class Super does not break binary compatibility with other classes in the
      example despite of the fact that the new field h hides field h, which is
      declared in the superclass Hyper with different type. But in accordance with
      new edition of the rule an incompatible class change should be detected
      while execution of the example.

      13.1 "The Form of a Binary" reads :

        The required properties are:
         * Given a legal expression denoting a field access in a class C, referencing
           a field named f declared in a (possibly distinct) class or interface D,
           we define the qualifying type of the field reference as follows:
              - If the expression is of the form Primary.f then the compile-time type
                of Primary is the qualifying type of the reference.
        The reference to f must be compiled into a symbolic reference to the qualifying
        type of the reference, plus the simple name of the field, f.

      So the classfile for Test should contain the reference "Super.h:Ljava/lang/String;"
      while the recompiled class Super declares now the field "h:I" of different type.
      This difference will lead to error while execution of the example.

      Note that javac vv. 1.2.2, 1.3fcs-C, 1.4.0beta-b23 generate Test.class with
      reference "Hyper.h:Ljava/lang/String;" which was demanded by JLS 1st ed.

      --------------------------------------=== Example

        In particular, no linkage error will occur in the case where a class could no
        longer be recompiled because a field access previously referenced a field of
        a superclass with an incompatible type. The previously compiled class with
        such a reference will continue to reference the field declared in a superclass.

        Thus compiling and executing the code:

           class Hyper { String h = "hyper"; }
           class Super extends Hyper { String s = "super"; }
           class Test {
                   public static void main(String[] args) {
                           System.out.println(new Super().h);

        produces the output:


        Changing Super to be defined as:

           class Super extends Hyper {
                   String s = "super";
                   int h = 0;

        recompiling Hyper and Super, and executing the resulting new binaries with
        the old binary of Test produces the output:


        The field h of Hyper is output by the original binary of main.





            gbrachasunw Gilad Bracha (Inactive)
            inevsunw Inev Inev (Inactive)
            0 Vote for this issue
            0 Start watching this issue