JDK-8214700 : Compilation fails when extend and implement same method signature with generics
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,11,12
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • OS: generic
  • CPU: x86_64
  • Submitted: 2018-11-29
  • Updated: 2018-12-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdUnresolved
Related Reports
Relates :  
Description
ADDITIONAL SYSTEM INFORMATION :
OS: 
- Windows 10 Pro (Version: 1803) 64 bit
- Ubuntu 18.04 LTS 64 bit

Java:
- 11.0.1 2018-10-16 LTS 
- 1.8.0_181

A DESCRIPTION OF THE PROBLEM :
I have a class, which extends a class and implements an interface. The interface has a method with a generic parameter at the method. The superclass has a method with the same signature except that the generic parameter is at the class. When I run the compiler the compilation fails with an error: 
C is not abstract and does not override abstract method getValue() in I

The Compiler of the current eclipse version (2018-09 (4.9.0)) compiles without errors.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the sourcecode from the testcase.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compilation is successful
ACTUAL -
Compilation fails with error:
Error:(1, 8) java: C is not abstract and does not override abstract method <T>getValue() in I

---------- BEGIN SOURCE ----------
public interface I {
  <T> T getValue();
}

public abstract class AC<T> {
  public T getValue() { return null; }
}

public class C extends AC<Integer> implements I {
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
You can move the generic Parameter from the method in the interface to the Interface:

public interface I<T> {
  T getValue();
}


Comments
Pending review: http://mail.openjdk.java.net/pipermail/compiler-dev/2018-December/012790.html
21-12-2018

Note that this error is only present with the pending fix for JDK-8207224 also applied.
07-12-2018

The attached patch fixes Dan's example by checking that return types are substitutable per JLS ��8.4.5 in both direct and inherited implementation (langtools:tier1 is OK) but a murky issue with the original example still exists: C.java:7: error: getValue() in AC cannot implement <T#2>getValue() in I public class C extends AC<Integer> implements I { ^ return type Integer is not compatible with T#2 where T#1,T#2 are type-variables: T#1 extends Object declared in class AC T#2 extends Object declared in method <T#2>getValue() 1 error Does this look correct?
07-12-2018

Here's a better test case (the choice of return type in the original test leads to some murky issues): public class JDK8214700 { public interface I { <T> T m1(); <T> T m2(); } public static class A { public Object m1() { return null; } } public static class B extends A implements I { public Object m2() { return null; } } } Both m1 and m2 are overridden via an erased signature (8.4.2, 4.6). javac gives unchecked warnings in both cases, but _also_ produces an error, claiming m1 has not been overridden. There is no error for m2. JDK8214700.java:11: error: B is not abstract and does not override abstract method <T>m1() in I public static class B extends A implements I { ^ where T is a type-variable: T extends Object declared in method <T>m1() JDK8214700.java:12: warning: [unchecked] m2() in B implements <T>m2() in I public Object m2() { return null; } ^ return type requires unchecked conversion from Object to T where T is a type-variable: T extends Object declared in method <T>m2() JDK8214700.java:11: warning: [unchecked] m1() in A implements <T>m1() in I public static class B extends A implements I { ^ return type requires unchecked conversion from Object to T where T is a type-variable: T extends Object declared in method <T>m1() 1 error 2 warnings
04-12-2018

When compiled provided test class 'C', getting compilation error using all JDK 8u192, 11.0.1+13, 12-ea+21 : C.java:1: error: C is not abstract and does not override abstract method <T>getValue() in I public class C extends AC<Integer> implements I { ^ where T is a type-variable: T extends Object declared in method <T>getValue() Note: C.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 1 error When workaround as provided in the description was applied, it compiled successfully.
03-12-2018