简体   繁体   English

重载泛型方法时Java 5和6之间的行为不同

[英]Differing behaviour between Java 5 & 6 when overloading generic methods

I've run into an issue in Java's Generics in which the same code will compile and work fine in Java 6, but will fail to compile because of the same erasure in Java 5. I have a file TestErasure.java that has an overloaded method, called "method": 我在Java的Generics中遇到了一个问题,其中相同的代码将在Java 6中编译并正常工作,但由于Java 5中的相同擦除而无法编译。我有一个文件TestErasure.java,它有一个重载的方法,称为“方法”:

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>()); 
 }
}

In Java 5, I get the expected compilation error, stating that the erasure of "method" is the same: 在Java 5中,我得到了预期的编译错误,指出“方法”的擦除是相同的:

$ 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

However, Java 6 is able to compile and run this same code. 但是,Java 6能够编译和运行相同的代码。

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

Based upon my current understanding of erasures (thanks to Jon Skeet and Angelika Langer ), I actually expected the compilation error as thrown by Java 5 (unless something changed in how Java handled Generics--which I can not find on the Java 6 release notes). 基于我目前对擦除的理解(感谢Jon SkeetAngelika Langer ),我实际上期望Java 5抛出编译错误(除非Java处理Generics的方式发生了变化 - 我在Java 6发行说明中找不到) )。 In fact, if I modify the return type of one of the overloaded methods: 实际上,如果我修改其中一个重载方法的返回类型:

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

Java 6 also fails to compile because of the same erasures: 由于相同的删除,Java 6也无法编译:

$ 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

It appears as if the return type in Java 6 somehow influences the selection of which overloaded method to use? 似乎Java 6中的返回类型以某种方式影响选择使用哪个重载方法?

Can someone shed light on why the first example works in Java 6--it seems to go against the stated handling of overloaded generic methods? 有人可以阐明为什么第一个例子在Java 6中工作 - 它似乎违背了重载泛型方法的声明处理?

More info: 更多信息:

Per David's suggestion, the original example, complied by javac 1.6, will run under the java 1.5: 根据David的建议,javac 1.6编写的原始示例将在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)

Found these bugs on Sun, which I think is what you're describing: 在Sun上发现了这些错误,我认为这就是你所描述的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM