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

Compiler fails to infer generic type

XMLWordPrintable

    • b66
    • x86
    • Verified

      FULL PRODUCT VERSION :
      java version "1.8.0_74"
      Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
      Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Windows 10,
      Fedora 22,


      A DESCRIPTION OF THE PROBLEM :
      When using JDK8 and using -source 1.8 -target 1.8 compiling of code provided below fails to compile with error
      "incompatible types: java.lang.Object cannot be converted to T"

      If we use -source 1.7 -target 1.7 JDK8 javac compiles the code without problems.

      Same code compiles on JDK7

      If we use JDK9-ea+107, it also compiles without problems no mater what -source/-target we use.

      Simple reproducer can also be found at https://github.com/ctomc/jdk8-compiler

      REGRESSION. Last worked in version 7u76

      ADDITIONAL REGRESSION INFORMATION:
      java version "1.7.0_72"
      Java(TM) SE Runtime Environment (build 1.7.0_72-b14)
      Java HotSpot(TM) Client VM (build 24.72-b04, mixed mode, sharing)

      It also compiles correctly when using JDK9-ea (both jigsaw and normal builds)
      java version "9-ea"
      Java(TM) SE Runtime Environment (build 9-ea+107-jigsaw-nightly-h4560-20160301)
      Java HotSpot(TM) 64-Bit Server VM (build 9-ea+107-jigsaw-nightly-h4560-20160301, mixed mode)

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Use JDK8 with -source 1.8 -target 1.8 and try to compile



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      compile successes
      ACTUAL -
      compile fails

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      Option.java:[12,37] incompatible types: java.lang.Object cannot be converted to T

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      public class Option {
          interface ValueParser<T> {
              T parseValue(String string, ClassLoader classLoader) throws IllegalArgumentException;
          }

          static <T> Option.ValueParser<T> getEnumParser(final Class<T> enumType) {
              return new ValueParser<T>() {
                  public T parseValue(final String string, final ClassLoader classLoader) throws IllegalArgumentException {
                      return enumType.cast(Enum.valueOf(enumType.asSubclass(Enum.class), string.trim()));
                  }
              };
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Rearrange code and manually cast.

        static <T, E extends Enum<E>> Option.ValueParser<T> getEnumParser(final Class<T> enumType) {
              return new ValueParser<T>() {
                  public T parseValue(final String string, final ClassLoader classLoader) throws IllegalArgumentException {
                      return enumType.cast(Enum.<E>valueOf(asEnum(enumType), string.trim()));
                  }
              };
          }

          @SuppressWarnings("unchecked")
          private static <T, E extends Enum<E>> Class<E> asEnum(final Class<T> enumType) {
              return (Class<E>) enumType;
          }

            akolarkunnu Abdul Kolarkunnu (Inactive)
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: