United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6182950 : methods clash algorithm should not depend on return type

Details
Type:
Bug
Submit Date:
2004-10-21
Status:
Closed
Updated Date:
2011-10-07
Project Name:
JDK
Resolved Date:
2011-10-07
Component:
tools
OS:
windows_vista,windows_xp
Sub-Component:
javac
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
5.0,6u21
Fixed Versions:

Related Reports
Duplicate:
Relates:
Relates:
Relates:

Sub Tasks

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

ADDITIONAL OS VERSION INFORMATION :

Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Following code should not compile:
class x {
    int f(List<String> l) {return 0;}
    double f(List<Integer> l) {return 0;}
}

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Following code should not compile:
class x {
    int f(List<String> l) {return 0;}
    double f(List<Integer> l) {return 0;}
}

since both method have the same erasure.
JLS3 draft 8.4.8.3 says, it is error if there are two methods m1 and m2 in a class such that:
- m1 and m2 have the same name
- m2 is accessible
- the signature of m1 is not subsignature if m2
- both methods have same erasure

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
    Error:  line (4) name clash: f(java.util.List<java.lang.String>) and f(java.util.List<java.lang.Integer>) have the same erasure

 
ACTUAL -
no error

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.List;
class x {
    int f(List<String> l) {return 0;}
    double f(List<Integer> l) {return 0;}
}
---------- END SOURCE ----------
###@###.### 10/21/04 23:19 GMT

                                    

Comments
SUGGESTED FIX

A webrev of this fix is available at the following URL:
http://hg.openjdk.java.net/jdk7/tl/langtools/rev/5caa6c45936a
                                     
2009-03-26
EVALUATION

Another potential problem:

class x {
    int f(List<String> l) {return 0;}
}

class y extends x {
    double f(List<Integer> l) {return 0;}
}

This program should be rejected according to 8.4.8.3 - there's no overriding between the two versions of f - currently javac allows this wrong overriding.
                                     
2009-01-05
EVALUATION

The submitter is right. Class x is not well-formed because the method signatures have the same erasure. Return type is not part of a signature, even though a return type should be erased at the same time as a signature (see 6730568).

For the record, given:

class x {
    int f(List<String> l) {return 0;}
    double f(List<Integer> l) {return 0;}
}

- f(List<String>) is not the same signature as f(List<Integer>).

- Then, f(List<String>) is not a subsignature of f(List<Integer>), because f(List<String>) does not have the same signature as f(List<Integer>) nor is f(List<String>) the same as the erasure of f(List<Integer>).

- Similarly, f(List<Integer>) is not a subsignature of f(List<String>).

- Thus they are not override-equivalent, which makes sense because you would never want to override f(List<Integer>) with f(List<String>).

- By 8.4.8.3, a compile-time error should occur because:
  - both methods have the same name
  - both are trivially accessible from x
  - the signature of f(List<String>) is not a subsignature of f(List<Integer>) (or vice-versa)
  - f(List<String>) has the same erasure as f(List<Integer>)

8.4.8.3 should be clarified to say: "***the signature of*** m1 or some other method...has the same erasure as ***the signature of m2*** or some other method...".
                                     
2006-10-26



Hardware and Software, Engineered to Work Together