2009-09-16 4 views
18

Wystąpił problem w języku Java Generics, w którym ten sam kod zostanie skompilowany i będzie działał poprawnie w Javie 6, ale nie uda się go skompilować z powodu tego samego usunięcia w Javie 5. mam TestErasure.java pliku, który ma przeciążone metody o nazwie „metoda”:Odmienne zachowanie między Java 5 i 6 podczas przeciążania ogólnych metod

import java.util.ArrayList; 
import java.util.List; 

public class TestErasure { 
public static Object method(List<Object> list) { 
    System.out.println("method(List<Object> list)"); 
    return null; 
} 

public static String method(List<String> list) { 
    System.out.println("method(List<String> list)"); 
    return null; 
} 

public static void main(String[] args) { 
    method(new ArrayList<Object>()); 
    method(new ArrayList<String>()); 
} 
} 

W Javie 5, uzyskać oczekiwany błąd kompilacji, stwierdzając, że wymazanie „metoda” jest taka sama:

$ javac -version 
javac 1.5.0_19 
$ javac TestErasure.java 
TestErasure.java:10: name clash: method(java.util.List<java.lang.String>) and method(java.util.List<java.lang.Object>) have the same erasure 
     public static String method(List<String> list) { 
          ^
TestErasure.java:17: method(java.util.List<java.lang.Object>) in TestErasure cannot be applied to (java.util.ArrayList<java.lang.String>) 
     method(new ArrayList<String>()); 
      ^
2 errors 

Jednak Java 6 jest w stanie skompilować i uruchomić ten sam kod.

$ javac -version 
javac 1.6.0_16 
$ javac TestErasure.java 
$ java TestErasure 
method(List<Object> list) 
method(List<String> list) 

Na podstawie mojego obecnego rozumienia wymazywania (dzięki Jon Skeet i Angelika Langer), tak naprawdę spodziewać się błąd kompilacji jak rzucony przez Java 5 (chyba, że ​​coś się zmieniło w sposobie Java obsługiwane Generics - których nie mogę znaleźć na informacje o wydaniu Java 6). W rzeczywistości, jeśli mogę zmienić typ zwracany jednego z przeciążonych metod:

public static Object method(List<Object> list) ... 
public static Object method(List<String> list) ... 

Java 6 również nie skompilować z powodu tych samych wymazywania: Wydaje

$ javac TestErasure.java TestErasure.java:5: name clash: method(java.util.List<java.lang.Object>) and method(java.util.List<java.lang.String>) have the same erasure 
    public static Object method(List<Object> list) { 
         ^
TestErasure.java:10: name clash: method(java.util.List<java.lang.String>) and method(java.util.List<java.lang.Object>) have the same erasure 
    public static Object method(List<String> list) { 
         ^
2 errors 

jakby typ zwracany w Java 6 w jakiś sposób wpływa na wybór, której przeciążonej metody użyć?

Czy ktoś może rzucić światło na to, dlaczego pierwszy przykład działa w Javie 6 - wydaje się, że jest to sprzeczne ze stwierdzoną obsługą przeciążonych ogólnych metod?

Więcej informacji:

sugestia Per Dawida, oryginalny przykład, przestrzegane przez javac 1.6, będzie działać pod Java 1.5:

$ javac -target 1.5 TestErasure.java 
$ java -version 
java version "1.5.0_19" 
$ java TestErasure 
method(List<Object> list) 
method(List<String> list) 
+0

The (usunięte) Typ zwrotny jest częścią m sygnatura ethod we wszystkich wersjach Java. –

+0

Typ zwracany jest częścią deskryptora metody, ale nie sygnaturą metody, prawda? http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#What%20is%20a%20method%20signature? –

+1

@ Tom - Wierzę, że się mylisz - "Definicja: Dwa komponenty deklaracji metody obejmują sygnaturę metody - nazwę metody i typy parametrów." Z http://java.sun.com/docs/books/tutorial/java/javaOO/methods.html. Podpis metody musi być unikalny, aby przeciążanie metody działało i nie zależy od typu zwracanego (przynajmniej w przypadku języka Java). – weiji

Odpowiedz

8

spotykane błędy na Słońcu, który moim zdaniem jest to, co „ponownego opisywania:

http://bugs.sun.com/view_bug.do?bug_id=6182950
http://bugs.sun.com/view_bug.do?bug_id=6730568

+0

Ten błąd wydaje się być wyświetlany w Netbeans 6.9. https://netbeans.org/bugzilla/show_bug.cgi?id = 187859 –

+0

Zestaw zmian db77bf6adb53 (23 października 2008 r.) przeciwko kodem OpenJDK 7 zawiera poprawkę: http://hg.openjdk.java.net/jdk7/build/langtools/rev/db77bf6adb53. – seh