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

Compiler erroneously reports incompatible types in code using the ?: operator

XMLWordPrintable

    • x86
    • linux

      FULL PRODUCT VERSION :
      java version "1.5.0_05"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
      Java HotSpot(TM) Client VM (build 1.5.0_05-b05, mixed mode, sharing)

      (identical version info on Linux and Windows)

      ADDITIONAL OS VERSION INFORMATION :
      Linux bl-chem-iumsc23.chem.indiana.edu 2.6.12-1.1381_FC3 #1 Fri Oct 21 03:46:55 EDT 2005 i686 i686 i386 GNU/Linux

      Microsoft Windows XP [Version 5.1.2600]

      A DESCRIPTION OF THE PROBLEM :
      The compiler wrongly reports incompatible types in some assignments when the left-hand side has a wildcard type and the right-hand side an intersection type arising from a ternary expression. It likewise wrongly rejects enhanced for loop control statements having similar construction. The compiler messages (see below) don't even make sense: how is it that test.Generic<capture of ? extends java.lang.Object&java.io.Serializable&test.Super> is not a subtype of test.Generic<? extends test.Super> ?


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      The problem can be reproduced by compiling the provided sample code (below) with javac 1.5.0_05.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The code should compile successfully and without warnings.
      ACTUAL -
      The compiler reported these errors:

      test/Test.java:32: incompatible types
      found : test.Generic<capture of ? extends java.lang.Object&java.io.Serializable&test.Super>
      required: test.Generic<? extends test.Super>
              generic = (flag ? new Generic<Sub3>() : new Generic<Sub4>());
                              ^
      test/Test.java:38: incompatible types
      found : java.lang.Object&java.io.Serializable&test.Super
      required: test.Super
              for (Super sup : (flag ? list3 : list4)) {}
                               ^
      2 errors


      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      As reported above.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      /*
       * An example file hilighting a javac (1.5.0_05) bug related to type capture
       * and the ternary operator
       */

      package test;

      import java.util.List;
      import java.io.Serializable;

      class Super {}
      class Sub1 extends Super {}
      class Sub2 extends Super {}
      class Sub3 extends Super implements Serializable {}
      class Sub4 extends Super implements Serializable {}
      class Generic<T> {}

      public class Test {

          List<Sub1> list1;
          List<Sub2> list2;
          List<Sub3> list3;
          List<Sub4> list4;

          public void test1(boolean flag) {
              Generic<? extends Super> generic;

              // This works
              generic = (flag ? new Generic<Sub1>() : new Generic<Sub2>());

              // This fails because of (supposed) incompatible types
              generic = (flag ? new Generic<Sub3>() : new Generic<Sub4>());

              // This works
              for (Super sup : (flag ? list1 : list2)) {}

              // This fails because of (supposed) incompatible types
              for (Super sup : (flag ? list3 : list4)) {}
          }

      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      An explicit cast can be used to avoid the error, but it still causes javac to emit an "unchecked cast" warning, and should not in any case be necessary.

            ahe Peter Ahe
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: