Java:当泛型为<t extends =“”parent =“”>时,是否在父类中转换为泛型类型?

时间:2017-02-02 18:33:50

标签: java generics casting

我有一个父类用于我的所有自定义异常,ParentException。我希望所有子异常都有一个向异常添加消息的方法。为此,我创建了一个泛型方法,在向其添加消息后返回泛型类型的对象。我在父类方法中使用sqoop export --connect 'jdbc:datadirect:cassandra://MyServer:9042;KeyspaceName=MyKS' --driver com.ddtek.jdbc.cassandra.CassandraDriver --table 'blah_1024MB' --export-dir /user/hdfs/blah_1024MB/ --input-lines-terminated-by "n" --input-fields-terminated-by ',' --batch -m 10 来添加消息然后返回this但是由于该方法返回泛型类型,我将其转换为泛型类型T.这似乎有效,但会发出警告。我的代码如下:

this

该行发出的警告是public class ParentException extends RuntimeException{ private String message; public ParentException() { message = ""; } public void addToMessage(String msg) { message += msg; } public void printMessage() { System.out.println(message); } public <T extends ParentException> T withMessage(String msg) { this.addToMessage(msg); return (T) this; // This line gives the warning } } 。这个方法似乎确实按预期工作,所以我并不担心,但我想更好地理解为什么它首先会发出警告。

这个演员总是安全吗?否则会导致运行时错误?

2 个答案:

答案 0 :(得分:1)

以下代码将编译,但在运行时将失败:

class ChildException extends ParentException { }

ParentException p = new ParentException();
ChildException c = p.withMessage("Connection failed");

我意识到写这个没有多大意义,但重点是编译器警告不安全的演员阵容可以首先防止这个地雷。

答案 1 :(得分:1)

考虑这种情况:

class SubException extends ParentException {...}

ParentException ex = new ParentException();
SubException sub = ex.withMessage("blah");

最后一行会抛出一个类强制转换异常,因为ParentException无法强制转换为SubException

您可以创建一个静态辅助方法:

class ParentException extends RuntimeException{
    ...
    protected static <T extends ParentException> T withMessage(T instance, String msg) {
        instance.addToMessage(msg);
        return instance;
    }

    public ParentException withMessage(String msg) {
        return withMessage(this, msg);
    }
}

并使用协变返回类型来覆盖此方法:

class SubException extends ParentException {
    @Override
    public SubException withMessage(String msg) {
        return withMessage(this, msg);
    }   
}

然后,如果您有SubException变量,则对withMessage的调用也会返回SubException