简体   繁体   English

Java:当泛型为时,在父类中强制转换为泛型类型是安全的 <T extends Parent> ?

[英]Java: Is casting to generic type in parent class safe when generic is <T extends Parent>?

I have a parent class for all of my custom exceptions, ParentException. 我的所有自定义异常都有一个父类ParentException。 I want all child exceptions to have a method that adds a message to the exception. 我希望所有子异常都具有一种向异常添加消息的方法。 To do this I created a generic method that returns an object of generic type after adding the message to it. 为此,我创建了一个通用方法,该方法在向其添加消息后返回通用类型的对象。 I use this in the parent class method to add the message then return this but since the method returns the generic type I casted it to the generic type T. This seems to work, but gives a warning. 我在父类方法中使用this方法来添加消息,然后返回this消息,但是由于该方法返回了泛型类型,因此将其强制转换为泛型T。这似乎可行,但会发出警告。 My code is as follows: 我的代码如下:

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
    }
}

The warning given by that line is Unchecked cast from ParentException to T . 该行给出的警告是Unchecked cast from ParentException to T The method does seem to work as expected, so I'm not worried but I'd like a better understanding of why this gives a warning in the first place. 该方法似乎确实按预期工作,因此我并不担心,但我想更好地理解为什么这首先会发出警告。

Will this cast always be safe? 这个演员会永远安全吗? Otherwise what case would cause a runtime error? 否则,哪种情况会导致运行时错误?

The following code will compile, but will fail at runtime: 以下代码将编译,但在运行时将失败:

class ChildException extends ParentException { }

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

I realize it wouldn't make much sense to write that, but the point is that the compiler warning about an unsafe cast can prevent this landmine in the first place. 我意识到编写它并没有多大意义,但是重点是,编译器警告有关不安全的强制转换可以从一开始就防止这种地雷。

Consider this case: 考虑这种情况:

class SubException extends ParentException {...}

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

The last line will throw a class cast exception, because ParentException can not be cast to SubException . 最后一行将抛出类ParentException异常,因为ParentException不能SubExceptionSubException


You could create a static helper method: 您可以创建一个静态帮助器方法:

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);
    }
}

And use covariant return types to override this method: 并使用协变返回类型覆盖此方法:

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

Then, if you have a SubException variable, the call to withMessage will return a SubException too. 然后,如果您有SubException变量,则对withMessage的调用withMessage将返回SubException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM