所以标题意味着我的问题有点奇怪和复杂.我知道我要做什么打破所有的“好”编程实践的规则,但是嘿,如果我们不生活有什么生活?
所以我做的是创建以下程序. (这不是一个更大的实验的一部分,真正尝试和理解泛型,所以一些功能名称可能有点不合格)
import java.util.*;
public class GenericTestsClean
{
public static void test2()
{
BigCage animalCage=new BigCage();
BigCage dogCage=new BigCage();
dogCage.add(new Dog());
animalCage.add(new Cat());
animalCage.add(new Dog());
animalCage.printList(dogCage);
animalCage.printList(animalCage);
}
public static void main(String [] args)
{
//What will this print
System.out.println("nTest 2");
test2();
}
}
class BigCage extends Cage
{
public static void printList(List list)
{
System.out.println("*************"Class().toString());
for(Object obj : list)
System.out.println("BigCage: "Class().toString());
}
}
class Cage extends ArrayList
{
public static void printList(List> list)
{
System.out.println("*************"Class().toString());
for(Object obj : list)
System.out.println("Cage: "Class().toString());
}
}
class Animal
{
}
class Dog extends Animal
{
}
class Cat extends Animal
{
}
现在让我感到困惑的是,它使用javac 1.6.0_26进行编译,但是当我运行它时,会得到以下类转换异常:
Test 2
*************class BigCage
BigCage: class Dog
*************class BigCage
Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to Dog
at BigCage.printList(GenericTestsClean.java:31)
st2(GenericTestsClean.java:13)
at GenericTestsClean.main(GenericTestsClean.java:21)
这里要注意的一些事情:
>两个printList不会被覆盖,但是按预期的方式重载(他们有不同的类型,因为它们的参数的泛型类型不同).这可以通过使用@Override注释进行验证
>将Cage类中的void printList(List)方法更改为非静态会生成适当的编译时错误
>更改方法void< U扩展Dog>类BigCage中的printList(List< U>)为void< U> printList(List< U>)生成适当的错误.
>在main()中通过BigCage类(即BigCage.printList(…))调用printList())生成相同的运行时错误
>在main()中通过Cage(即Cage.printList(…))调用printList()的工作原理只有在Cage中调用printList的版本
>如果我将printList(List)的定义从Cage类复制到BigCage类,这将隐藏Cage类中的定义,我得到了相应的编译器错误
现在如果我不得不在黑暗中拍摄一下这里发生了什么,我会说编译器正在拧紧,因为它在多个阶段工作:类型检查和重载方法解析.在类型检查期间,我们通过违规行,因为BigCage类继承了Cage类中的void printList(List),它将匹配我们抛出的任何旧列表,所以确保我们有一个可以工作的方法.但是,一旦遇到实际调用的方法来解决问题,我们就会遇到类型擦除问题,这会导致BigCage.printList和Cage.printList都具有完全相同的签名.这意味着当编译器正在寻找一个匹配的animalCage.printList(animalCage);它将选择它匹配的第一种方法(如果我们假设它从底部开始使用BigCage,并且将它的原因作为Object),它会找到void< U extends Dog> printList(List< U>)而不是正确的匹配void printList(List)
现在我真正的问题:我在这里接近真相?这是一个已知的错误吗?这是一个bug吗?我知道如何解决这个问题,这更像是一个学术问题.
**EDIT**
As few people have posted below,this code will work in Eclipse.
My specific question deals with javac version 1.6.0_26. Also,I’m not
sure if I completely agree with Eclipse in this case,even though it
works,because adding a printList(List>) to BigCage will
result in a compile time error in Eclipse and I can’t see reason why
it should work when the same method is inherited verses manually
added (See Note 6 above).
本文发布于:2024-02-01 09:59:05,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170675274535839.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |