当前位置: 首页 > 知识库问答 >
问题:

Java:当泛型是时,在父类中强制转换为泛型类型是否安全?

庄嘉
2023-03-14

我有一个父类来处理我所有的自定义异常,父母异常。我希望所有的子异常都有一个方法来向异常添加消息。为了做到这一点,我创建了一个泛型方法,在向其添加消息后返回泛型类型的对象。我在父类方法中使用this来添加消息,然后返回this,但是由于该方法返回泛型类型,所以我将其转换为泛型类型T。这似乎是可行的,但是给出了警告。我的代码如下:

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

该行给出的警告是从ParentException强制转换为T。这种方法似乎确实如预期的那样有效,所以我并不担心,但我想更好地理解为什么这会在第一时间发出警告。

这个强制转换总是安全的吗?否则什么情况会导致运行时错误?

共有2个答案

尹何平
2023-03-14

考虑这种情况:

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

然后,如果您有一个SubExctive变量,对with Message的调用也将返回一个SubExctive

颛孙俊
2023-03-14

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

class ChildException extends ParentException { }

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

我意识到写这个没有多大意义,但关键是编译器警告不安全的强制转换可以首先阻止这个地雷。

 类似资料:
  • 我有一个通用类。它看起来像这样: 显然,conevertdatajsonstring方法仅在字符串类型为T时调用。但有一个警告: 类型安全:未选中从字符串转换为T 有没有一种方法可以在不使用SuppressWarnings的情况下解决此问题: @抑制警告(“未选中”) 方法之前?

  • 我在我的一个实用程序类中有一个方法,它接受一个集合和一个类对象,并返回一个Iterable实例,该实例可以遍历作为指定类实例的集合的所有成员。其签名为: 这对于大多数用例都非常有效,但现在我需要将其与泛型类

  • 我正在修改open JDK以添加特性,我已经遇到了两次,但没有好的解决方案。

  • 问题内容: 我遇到了Java的异常行为,似乎是一个错误。是吗?即使对象不是的实例,也无法将对象强制转换为通用类型(例如)。这是一个例子: 更新 :感谢cletus和Andrzej Doyle的有用答案。因为我只能接受一个,我接受安杰伊·多伊尔的答案,因为它使我一个解决方案,我觉得是不是 太 糟糕。我认为这是在单行代码中初始化小型Map的更好方法。 然后您这样称呼它: 问题答案: 就像cletus所

  • 在下面来自的语法中,泛型类型参数在实例化原始类型数组后用于类型转换,

  • 我想说得具体一点。我有一个名为Result的类和一个名为Result的派生类 这些类在方法中用作返回类型。为此,我创建了这个helper类: 正如您所看到的,上面的代码对于成功有两种返回类型,一种是如果您不想返回任何东西,另一种是如果您想返回一些东西,但是失败的结果永远不会返回什么东西。这是不必要的,只是一个错误消息。这使我想到以下问题:当我想创建一个可以使用返回类型返回Success,而不使用返