Java对象转换无法正常工作,因为我需要它 [英] Java object casting doesn't work like I need it to
问题描述
我正在Java上开发本机Android应用程序,但是遇到了一些意外的行为.看一下这些类:
I'm developing native Android app on Java and I faced some unexpected behavior. Look at these classes:
public class Parent<C> {
protected C mCallback;
public void setCallback(Object callback) {
mCallback = (C)callback;
}
}
class Child<T extends Vehicle>
extends Parent<Child.Callback<Vehicle>>{
public void invoke(){
mCallback.onAction(new Vehicle());
}
public interface Callback<T> {
void onAction(T vehicle);
}
}
class Vehicle {
}
现在
Child<Vehicle> child = new Child<Vehicle>();
child.setCallback(new Object()); // I expect ClassCastException to be thrown here!
child.invoke(); //But it's thrown only here!
为什么.setCallback()方法中没有引发ClassCastException?
为什么只有当我尝试访问回调接口的方法时才会抛出该异常?
如何检查对象回调是C的实例?或者至少如何在setCallback()方法中获取ClassCastException?
P.S.这是简化的示例!请在此处考虑相同但真实的问题:如何检查在Fragment.onAttach()中键入回调类型
P.S. This is simplified example! Please consider the same, but real life question here: How to check typed callback type inside Fragment.onAttach()
One of the solutions proposed by @luckydog32 in comments here
public abstract class Parent<C> {
protected C mCallback;
public void setCallback(Object callback) {
mCallback = castCallback(callback);
}
protected abstract C castCallback(Object callback) throws ClassCastException;
}
class Child<T extends Vehicle>
extends Parent<Child.Callback<Vehicle>>{
@Override
protected Callback<Vehicle> castCallback(Object callback) throws ClassCastException {
return (Callback<Vehicle>)callback;
}
public void invoke(){
mCallback.onAction(new Vehicle());
}
public interface Callback<T> {
void onAction(T vehicle);
}
}
推荐答案
这是因为称为类型为擦除.基本上,在您编译程序之后,泛型类型将替换为其上界.例如
This is because of something called Type Erasure. Basically after you program is compiled generic types are replaced with their Upper Bound. So for example
class Child<T extends Vehicle>
每个T实例都被当作是Vehicle类.
Every instance of T is just treated as if it were a Vehicle class.
因此在代码中:
public void setCallback(Object callback) {
mCallback = (C)callback;
}
在运行时,您几乎是在说:
During run time you are pretty much saying:
public void setCallback(Object callback) {
mCallback = (Object)callback;
}
由于您要立即投射回调,因此只需修改代码即可:
Since you are casting callback immediately, the simple fix for your code would to just do:
public void setCallback(C callback) {
mCallback = callback;
}
这篇关于Java对象转换无法正常工作,因为我需要它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!