为什么我必须强制转换constructor.newinstance的返回?

ma8fv8wu  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(291)

根据文档,newinstance()返回一个t:https://docs.oracle.com/javase/7/docs/api/java/lang/class.html#newinstance()
如果我有一个返回t的方法,为什么我要将constructor.newinstance()的返回转换为t?

protected <T extends ParentClass> T getConfig() {
  return (T) _childClassConstructor.newInstance();
nbysray5

nbysray51#

泛型是编译器想象的产物:运行时( java.exe )不知道这意味着什么,不在乎,而且大多数情况下,甚至没有这些信息(“擦除”)。是的,公共签名确实包含泛型信息,但就运行时而言,它实际上是一个注解。
那么,它到底有什么用呢?
嗯,它把事情联系起来了。它可以告诉编译器:所以,我有这个方法,它需要两个参数。这两个参数可以是任意的,但是,它们必须是相同的类型。如果没有,运行时就不会进行核心转储或其他任何操作,只是。。这意味着软件有缺陷。所以,如果你看到的代码不符合这个规则,请标记一个错误,这样我就知道我需要修复它。
泛型就是这么做的。但幸运的是,这是相当有用的!
如果你使用泛型,它们只出现在一个地方,那基本上是没用的,或者说是黑客。您已经在这里完成了:t只显示一次,作为这个方法的返回类型,而不是其他任何地方。实际上,这总是表明代码的作者不理解java的泛型做什么。
在本例中,您有效地完成了将其转换为巫毒魔法的任何方法-此方法将调整其返回类型,使其成为调用者希望的任何类型。鉴于 class Parent 以及 class Joe extends Parent 以及 class Jane extends Parent ,则这将起作用:

Joe c = getConfig();

你怎么能 getConfig() 知道它的返回类型实际上是 Joe ? 没有。它会适应你想要的样子。
这是一件坏事-因为如果你看代码,它实际上不是这样工作的:

class ConfigTool {
    private final Class<? extends Parent> c;

    public ConfigTool(Class<? extends Parent> c) {
        this.c = c;
    }

    public <T extends ParentClass> T getConfig() {
        return (T) c.newInstance();
    }
}

以及:

ConfigTool tool = new ConfigTool(Jane.class);
Joe joe = tool.getConfig();

只会编译。当然,在运行时爆炸 getConfig() 方法最终生成 Jane ,它不能赋给joe类型的变量,这意味着没有简单的“这是如何修复代码”的答案,因为你所写的是毫无意义/不可能的。
你大概打算做两件事之一:
或者:

public ParentClass getConfig() {
    return c.newInstance();
}

当然,也许吧 c 是代表joe的类示例,但也可能是jane。您的api所能做的唯一承诺是,无论类示例是什么,它所做的任何示例都将可赋值给parent类型的变量。毕竟, Parent p = new Joe(); 是有效的 Parent p = new Jane(); .
没有必要涉及泛型。泛型是更高的一个“元”级别:它将类型系统本身转化为一种编程语言,在这里您不需要这样做。
您可能需要的另一种选择是链接 getConfig() 方法来指定此对象的类示例的特定类型:

class ConfigTool<T extends Parent> {
    private final Class<T> c;

    public ConfigTool(Class<T> c) {
        this.c = c;
    }

    public T getConfig() {
        return c.newInstance();
    }
}

请注意,在这段代码中,完全不需要强制转换,上面的代码是按编写的那样编译的。泛型也很有用,因为t出现在两个地方:两个 Class<T> 构造函数中的参数,以及 T 的返回类型 getConfig 方法(在 class Parent<T> 不算数,那不是在使用它,那是在定义它的存在)。

相关问题