强制转换“类型擦除”的对象是否安全?

时间:2019-06-30 06:29:24

标签: java oop generics type-erasure

一个类(实现通用接口)具有一个返回java.lang.Object数据类型而不是预期数据类型的方法。在调用方语句中进行强制转换是否安全?

import java.io.*; 
import java.lang.*;

interface dataCharge<A>{
    public A change(A ele); 
}

class APCDcharge implements dataCharge<APCDcharge>{
    private String name;
    private Integer charge;
    public void setName(String name){
        this.name = name;
    }
    public void setCharge(Integer charge){
        this.charge = charge;
    }
    public String getName(){
        return name;
    }
    public Integer getCharge(){
        return charge;
    }
    public String getKey(){
        return name+":"+charge;
    }
    @Override
    public APCDcharge change(APCDcharge ele){
        APCDcharge newele = new APCDcharge();
        newele.setCharge(ele.getCharge()+100);
        newele.setName(ele.getName());
        return newele;
    }
}

public class Main {
    public static void main(String[] args) {
        APCDcharge c = new APCDcharge();
        c.setName("ABC");
        c.setCharge(100);
        APCDcharge d = timePass(c);
        System.out.println(d.getKey());
    }
    private static <T extends dataCharge> T timePass(T element){
        T res = element.change(element);
        return res;
    }
}

上面的代码片段给出了错误:

error: incompatible types: Object cannot be converted to T T res = element.change(element);

我还尝试使用element.change(element)数据类型进行T的类型转换:

T res = (T)element.change(element);

并且代码正在编译(警告:Note: Main.java uses unchecked or unsafe operations.),但执行正确。那是消除错误的安全方法吗?还有其他纠正方法吗?

2 个答案:

答案 0 :(得分:3)

您的问题是,在您的static方法中,T的类型边界是原始类型(dataCharge)。

进行以下更改:

private static <T extends dataCharge<T>> T timePass(T element){
    T res = element.change(element);
    return res;
}

T extends dataCharge<T>而不是T extends dataCharge

现在,代码将在不进行强制转换的情况下通过编译。

答案 1 :(得分:0)

此方法:

static <T extends dataCharge> T timePass(T element){
    T res = element.change(element);
    return res;
}

使用原始(即未键入)dataCharge。您应该键入它,并返回dataCharge的类型,而不是dataCharge的(子类)。

鉴于您使用它的方式(即将其传递到自己的方法中),建议dataCharge应该更简单地定义为dataCharge供应商,在创建结果时直接访问自己的状态:

interface dataCharge<A>{
    public A change(); 
}

class APCDcharge implements dataCharge<APCDcharge> {
    // other code

    @Override
    public APCDcharge change() {
    APCDcharge newele = new APCDcharge();
    newele.setCharge(getCharge()+100);
    newele.setName(getName());
    return newele;
    }
}

然后您的timePass方法变为:

static <T> T timePass(dataCharge<T> element){
    T res = element.change();
    return res;
}