JDK-6979815 : Compiler accepts 2 methods with override-equivalent signatures
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u21
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_vista
  • CPU: x86
  • Submitted: 2010-08-25
  • Updated: 2012-03-20
  • Resolved: 2010-12-01
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_21"
Java(TM) SE Runtime Environment (build 1.6.0_21-b07)
Java HotSpot(TM) Client VM (build 17.0-b17, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.0.6001]

A DESCRIPTION OF THE PROBLEM :
I think this is a regression of Bug 6182950. The following compiles, but it should not:

import java.util.List;
class X {
    int f(List<String> l) {return 0;}
    double f(List<Integer> l) {return 0;}
}



A) However, he original report seems to reason incorrectly.
Section 8.4.3.3 does not apply because
the signature of f(List<String>) IS a subsignature of f(List<Integer>) (and vice-versa)
according to section 8.4.2:
"The signature of a method m1 is a subsignature of the signature of a method m2 if either
  - m2 has the same signature as m1, or
  - the signature of m1 is the same as the erasure of the signature of m2"

The 2nd criterion applies, I think (see section "4.6 Type Erasure"):

 - The erasure of a parameterized type (��4.5) G<T1, ... ,Tn> is |G|.
 - The erasure of a method signature s is a signature consisting of the same name as s, and the erasures of all the formal parameter types given in s.

Thus f(List<String>) and f(List<Integer>) both become f(List) and thus, m1 is a subsignature of m2 and vice versa (they are override-equivalent).

(Note that the return type is not part of a method's signature!)



B) The code still must not compile. The reason can be found in "8.4.2 Method Signature":
"It is a compile-time error to declare two methods with override-equivalent signatures (defined below) in a class."

"Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1."

Since both methods have the same name and override-equivalent signatures and are in the same class, the code should not compile. (Eclipse Helios correctly reports this.)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile the following code:

import java.util.List;
class X {
    int f(List<String> l) {return 0;}
    double f(List<Integer> l) {return 0;}
}

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Code does not compile:
Error:  line (4) name clash: f(java.util.List<java.lang.String>) and f(java.util.List<java.lang.Integer>) have the same method name with override-equivalent signatures.

ACTUAL -
No error. The code compiles correctly. (and behaves correctly, because the JVM can still distinguish the methods by their return types, whereas the language spec prohibits it).

REPRODUCIBILITY :
This bug can be reproduced always.