| Summary: | Wrong binding of methods from Object in default method with type parameter | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Marko van Dooren <Marko.van.Dooren> |
| Component: | Core | Assignee: | Sasikanth Bharadwaj <sasikanth.bharadwaj> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | manoj.palat |
| Version: | 4.5 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Mac OS X | ||
| Whiteboard: | stalebug | ||
Since neither clone() method can be determined to be more specific than the other based on signature, we are using the rule that concrete method is more specific than abstract or default methods which seems to be in order with section 15.12.2.5 of the spec If all the maximally specific methods have override-equivalent signatures (§8.4.2), then: – If exactly one of the maximally specific methods is concrete (that is, nonabstract or default), it is the most specific method. Casting 't' to 'I' gets the code to compile. The upper bound of T is I, which is an interface. According to section 9.2 of the language specification, an interface does not inherit concrete methods from Object. Therefore, there is no concrete method that can be more specific than I.clone(). Also note that the problem does not occur when moving the exact same implementation to some unrelated class (the call is still done on an object of type paramater T with upper bound I). This should not make a difference at all. This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie. |
When a method from Object is "overridden" in an interface I, and that method is invoked in a default method of I on an object of type T where T is a type parameter with upperbound I, the "overriding" method in I is ignored (the type parameter is needed to trigger the bug). The example below illustrates the problem. The default method does not compile in Eclipse. But it does compile with the JDK compiler (javac 1.8.0_31). public interface I { // Compiles with javac, but not with Eclipse default <T extends I> void compilesInJDKCompiler(T t) { t.clone(); } I clone(); } Hovering over the method shows that it resolves to Object.clone() while the compiler is allowed to assume I.clone() because any class that implements I must respect I.clone() anyway. If we write the same method as a regular method of an unrelated class C, the problem disappears: public static class C { // Compiles with javac AND with Eclipse public <T extends I> void compilesInJDKCompiler(T t) { t.clone(); } } The problem also disappears when the parameter type is changed to I instead of using the type parameter of the method. public interface I { // Compiles with javac AND with Eclipse default void compilesInJDKCompiler(I t) { t.clone(); } void clone(); } The problem also occurs for e.g. finalize() (works with javac, but no with Eclipse). I can't trigger the problem with other methods because there is nothing to specialize: they have no checked exceptions and no return type that can be changed. It seems like the bound of T is ignored in default methods.