我正在循环ArrayList<Bar>
.Foo
延伸Bar
.我正在尝试Foo
在列表中找到一个实例.
ArrayList<Bar> list = new ArrayList<Bar>();
// fill list with items that are instances of Foo and Bar
for (int i = 0; i < list.size(); i++)
{
Bar bar = list.get(i);
if (bar.getClass().getName().equals("com.me.Foo")) // "if(bar instanceof Foo)" never passes
{
System.out.println("bar is an instance of Foo");
Foo foo = (Foo) bar;
}
}
Run Code Online (Sandbox Code Playgroud)
如果此部分代码运行,我会收到此错误:
java.lang.ClassCastException: com.me.Foo cannot be cast to com.me.Foo
// stack
Run Code Online (Sandbox Code Playgroud)
但是,在另一个地方,我有一个方法返回一个实例,Bar
我可以检查它是否是一个Foo
使用的实例instanceof
然后Bar
转换Foo
为没有问题:
Bar bar = returnBar(); // returns an instance of Bar, but the variable
// it returns could be an instance of Foo
if (bar instanceof Foo)
{
System.out.println("bar is an instance of Foo");
Foo foo = (Foo) bar;
}
Run Code Online (Sandbox Code Playgroud)
这有什么不同?
以下是该问题的真正来源:http: //pastie.org/private/jhyhovn7mm4ghxlxsmweog
我正在使用一个名为Bukkit的API,它允许为名为Minecraft的游戏提供服务器的自定义插件.可以在此处找到对该问题真正感兴趣的人员的文档.我将去官方Bukkit论坛并在那里尝试我的问题,因为它变得更具API特定问题,但我将把这一切留给那些对这个问题感兴趣的人.
Jon*_*eet 17
我的猜测是你Foo
从两个地方装货.在你的循环,尝试打印出来bar.getClass().getClassLoader()
和Foo.class.getClassLoader()
.我怀疑他们会展示不同的类加载器.(你可能有两个类加载器从同一个地方加载,当然,这同样很糟糕.)
基本上,就JVM而言,从不同类加载器加载的两个具有相同名称的类完全不同 - 您不能从一个类转换为另一个类.假设我对此是正确的,通常的解决方案是尝试找出为什么他们从不同的类加载器加载,并解决它.
请注意,当您使用时instanceof
,检查类型是否真正兼容,因此它会注意到不同的类加载器.