Java通用以避免ClassCastException [英] Java generic to avoid ClassCastException

查看:183
本文介绍了Java通用以避免ClassCastException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我正在处理的一段代码。我有一个回调对象,可以返回指定的超类型。 车辆就是这里的一个类。这些类在这里用作其他类的超类型,如 Car Train

  interface CompletionCallBack< Result> {
void onCompletion(结果结果);
}

class车辆{
Map< String,Object>属性;
}

class Car延伸车辆{
public String getMake(){
return attributes.get(make)。toString();



class train {
public String getMake(){
return attributes.get(size)。toString() ;



public class Main {
static void execute(CompletionCallBack< Vehicle> callBack){
callBack.onCompletion(new Vehicle()) ;
}

public static void main(String [] args){
execute(new CompletionCallBack< Vehicle>(){
@Override
public void onCompletion(Vehicle result){
Car car =(Car)result; // Exception
}
});
execute(new CompletionCallBack< Vehicle>(){
@Override
public void onCompletion(Vehicle result){
Train train =(Train)result; // Exception

}
});






$ b这里我得到了ClassCastException,因为Vehicule不能直接转换为汽车或火车。我想调用 execute 给它一个像 Car Train <


$ b $ $ $ $ $



$静态无效executeGeneric(CompletionCallBack< ?extend Vehicle> callBack){
callBack.onCompletion(new Vehicle()); //编译错误
}

public static void main(String [] args){
executeGeneric(new CompletionCallBack< Car>(){
@Override
public void onCompletion(Car car){
//我在这里收到一辆车
}
});
}
}

我正在尝试这样做,因为在我的情况下,车辆包含一个属性映射和一个 Car 车辆,该车辆在该列表中具有一些键值对。火车有其他人。我的 Car Train 对象提供了简单的getter,它知道从 Map



我能做到这一点的唯一方法是移除父子关系并围绕<$ c构建一个装饰器$ c> Vehicle 为我的 Train Car 类。

解决方案

问题在于你有一个适用于任何车辆的机制,无需区分汽车和火车 - 但是你希望汽车和火车有不同的行为。

因此有以下几种解决方案:

1)拆分机制让你拥有不同的类型, 2)使用多态 - 在Vehicle中提供的方法可以在Car和Train中以不同的方式进行调用,并在回调中调用这些方法。
$ b $ 3)如果一切都失败了,使用 instanceof 来检测对象的实际类型,然后将其转换为汽车或火车。

Here is a piece of code I'm working on. I have a Callback object that can return a specified super type. Vehicle is one of these classes here. These classes are used as supertype for other classes like Car and Train here.

interface CompletionCallBack<Result> {
    void onCompletion(Result result);
}

class Vehicle {
    Map<String, Object> attributes;
}

class Car extends Vehicle {
    public String getMake(){
        return attributes.get("make").toString();
    }
}

class Train extends Vehicle {
    public String getMake(){
        return attributes.get("size").toString();
    }
}

public class Main {
    static void execute(CompletionCallBack<Vehicle> callBack) {
        callBack.onCompletion(new Vehicle());
    }

    public static void main(String[] args) {
        execute(new CompletionCallBack<Vehicle>() {
            @Override
            public void onCompletion(Vehicle result) {
                Car car = (Car) result; //Exception
            }
        });
        execute(new CompletionCallBack<Vehicle>() {
            @Override
            public void onCompletion(Vehicle result) {
                Train train = (Train) result; //Exception

            }
        });
    }
}

Here I get ClassCastException as Vehicule cannot be directly casted to Car or Train. I would like to either call the execute giving it a type like Car or Train like so :

public class Main {

    static void executeGeneric(CompletionCallBack<? extends Vehicle> callBack) {
        callBack.onCompletion(new Vehicle()); //compilation error
    }

    public static void main(String[] args) {
        executeGeneric(new CompletionCallBack<Car>() {
            @Override
            public void onCompletion(Car car) {
                //I receive a car here
            }
        });
    }
}

I'm trying to do this because in my case, Vehicle contains a map of attribute and a Car a vehicle that has some key-value pair in that list. Train has others. My Car and Train object provides easy getter that knows the specific keys to retrieve data from the Map.

The only way I was able to do it was to remove the parent-child relation and build a decorator around a Vehicle for my Train and Car classes.

解决方案

The problem is that you have a mechanism that should work for any Vehicle, without distinguishng between Car and Train - yet you want different behaviour for Car and Train.

So there are several solutions:

1) Split up the mechanism so you have different, typed, callbacks for Car and Train

2) Use polymorphism - provide method(s) in Vehicle that you over-ride differently in Car and Train, and call these in the callbacks.

3) If all else fails, use instanceof to detect the actual type of the object before casting it to Car or Train.

这篇关于Java通用以避免ClassCastException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆