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

Missing synthetic casts when accessing fields/methods of intersection types including type variables

XMLWordPrintable

    • b27
    • generic
    • windows_xp
    • Not verified

      JLS 4.4. says:
      The members of a type variable X with bound T & I1 ... In are the members of the intersection type (§4.9) T & I1 ... In appearing at the point where the type variable is declared.

      JLS 4.9 Intersection Types
      The members of an intersection type T1 & ... & Tn are determined as follows:
         1. For each Ti, 1in, let Ci be the most specific class or array type such that Ti <: Ci Then there must be some Tk <: Ck such that Ck <: Ci for any i, 1in, or a compile-time error occurs.
         2. For 1jn, if Tj is a type variable, then let ITj be an interface whose members are the same as the public members of Tj; otherwise, if Tj is an interface, then let ITj be Tj.
         3. Then the intersection type has the same members as a class type (§8) with an empty body, direct superclass Ck and direct superinterfaces IT1 , ..., ITn, declared in the same package in which the intersection type appears.

      -------------------------------------------------------------------------

      The test below declares the generic method testMethod with the type parameters <W extends C & I & I1 & I2, T extends W>, where C is a class, I, I1, I2 - interfaces. W - type variable with the bound C & I & I1 & I2.

          static <W extends C & I & I1 & I2, T extends W> void testMethod(T t)

      1. According to 4.4 the members of a type variable T with bound W are the members of the intersection type W.
      2. According to 4.9.3 intersection type W has the same members as a class type with an empty body and direct superinterface IW.
      3. According to 4.9.2 IW is an interface whose members are the same as the public members of W.
      4. According to 4.4 the members of a type variable W with bound C & I & I1 & I2 are the members of the intersection type C & I & I1 & I2.
      5. According to 4.9.1, 4.9.3 intersection type C & I & I1 & I2 has the same members as a class type with an empty body and direct superclass C and direct superinterfaces I & I1 & I2.

      So, according point 4,5, W has the same members as all members af C (except private members), I, I1 and I2.
      So, according point 3, IW has the same members as all members af C (except private AND PROTECTED members), I, I1 and I2.
      So, according point 1, the members of a type variable T are the same as PUBLIC members of C and all members of I, I1 and I2.

      But in the test code below PROTECTED member of C is accessible from testMethod().
      But methods of I, I1 and I2 are not accessible in runtime.

      ---------------------------Test.java------------------------------
      package javasoft.sqe.tests.lang.TYPE.TESTS;

      import java.io.PrintStream;

      class C {
          public void mCPublic() {}
          public void mCProtected() {}
      }

      interface I {
          void mI();
      }

      interface I1 {
          void mI1();
      }

      interface I2 {
          void mI2();
      }

      class CI extends C implements I, I1, I2 {
          public void mI() {}
          public void mI1() {}
          public void mI2() {}
      }

      public class Test {
          public static int run(String argv[], PrintStream out) {
              testMethod(new CI());
              return 0/*STATUS_PASSED*/;
          }

          public static void main(String argv[]) {
              System.exit(run(argv, System.out) + 95/*STATUS_TEMP*/);
          }

          static <W extends C & I & I1 & I2, T extends W> void testMethod(T t) {
              t.mCPublic(); // OK
              t.mI(); // should be OK, but not (see OutPut1)
              t.mI1(); // should be OK, but not (see OutPut2)
              t.mI2(); // should be OK, but not (see OutPut3)
              t.mCProtected(); // should rise to a compile-time error, but don't
          }
      }

      ------------------OutPut1---------------------------
      Exception in thread "main" java.lang.NoSuchMethodError: javasoft.sqe.tests.lang.TYPE.TESTS.C.mI()V
      at javasoft.sqe.tests.lang.TYPE.TESTS.Test.testMethod(Test.java:40)
      at javasoft.sqe.tests.lang.TYPE.TESTS.Test.run(Test.java:30)
      at javasoft.sqe.tests.lang.TYPE.TESTS.Test.main(Test.java:35)
      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
      at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
      at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
      at java.lang.reflect.Method.invoke(Method.java:597)
      at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)

      ------------------OutPut2---------------------------
      Exception in thread "main" java.lang.NoSuchMethodError: javasoft.sqe.tests.lang.TYPE.TESTS.C.mI1()V

      ------------------OutPut3---------------------------
      Exception in thread "main" java.lang.NoSuchMethodError: javasoft.sqe.tests.lang.TYPE.TESTS.C.mI2()V

            mcimadamore Maurizio Cimadamore
            ynovozhi Yulia Novozhilova (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: