class World{
<T extends Class1> World(TreeSet<? extends ClassA> set){
*some code*
}
<T extends Class2> World(TreeSet<? extends ClassB> set){
*some code*
}
}
以上代码显示错误“名称冲突:
答案 0 :(得分:0)
我在包含以下方法的类上使用Intellij Idea的Bytecode Viewer插件检查了问题:
public <A extends Calendar> void fn(ArrayList<? extends File> abc){ //line number:11
A a=(A)new Object(); //line 12
} //line number:13
下面是字节码查看器中与此方法相对应的字节码:
// access flags 0x1
// signature <A:Ljava/util/Calendar;>(Ljava/util/ArrayList<+Ljava/io/File;>;)V
// declaration: void fn<A extends java.util.Calendar>(java.util.ArrayList<?extends java.io.File>)
public fn(Ljava/util/ArrayList;)V
L0
LINENUMBER 12 L0
NEW java/lang/Object
DUP
INVOKESPECIAL java/lang/Object.<init> ()V
CHECKCAST java/util/Calendar
ASTORE 2
L1
LINENUMBER 13 L1
RETURN
L2
LOCALVARIABLE this LMain; L0 L2 0
LOCALVARIABLE abc Ljava/util/ArrayList; L0 L2 1
// signature Ljava/util/ArrayList<+Ljava/io/File;>;
// declaration: java.util.ArrayList<? extends java.io.File>
LOCALVARIABLE a Ljava/util/Calendar; L1 L2 2
// signature TA;
// declaration: A
MAXSTACK = 2
MAXLOCALS = 3
看上面的第二行。尽管已注释掉,但保留了具有适当范围的类型参数。但是方法签名在编译后不包含任何类型参数(第4行)。我们在第10行中再次看到保留的类型参数信息用于转换,它对应于原始代码的第12行。因此得出的结论是类型参数并没有被其边界完全取代。您的编译文件将保留有关类型参数及其范围的信息。仅在编译器确定需要时才使用此保留的信息。出于某种原因,编译器认为方法(或构造函数)不需要在编译文件中的声明中包含这些信息(这解释了“相同擦除”错误部分)。当它不具有通用功能时,其原因与对Java版本的向后兼容性有关。因此,仅更改/添加/删除类型参数和/或其边界不会使方法或构造函数过载。
我知道我的回答是粗略的,但据我所知并非错误。请提出我在评论中缺少的任何内容,或发表您自己的答案。