根据文档,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();
1条答案
按热度按时间nbysray51#
泛型是编译器想象的产物:运行时(
java.exe
)不知道这意味着什么,不在乎,而且大多数情况下,甚至没有这些信息(“擦除”)。是的,公共签名确实包含泛型信息,但就运行时而言,它实际上是一个注解。那么,它到底有什么用呢?
嗯,它把事情联系起来了。它可以告诉编译器:所以,我有这个方法,它需要两个参数。这两个参数可以是任意的,但是,它们必须是相同的类型。如果没有,运行时就不会进行核心转储或其他任何操作,只是。。这意味着软件有缺陷。所以,如果你看到的代码不符合这个规则,请标记一个错误,这样我就知道我需要修复它。
泛型就是这么做的。但幸运的是,这是相当有用的!
如果你使用泛型,它们只出现在一个地方,那基本上是没用的,或者说是黑客。您已经在这里完成了:t只显示一次,作为这个方法的返回类型,而不是其他任何地方。实际上,这总是表明代码的作者不理解java的泛型做什么。
在本例中,您有效地完成了将其转换为巫毒魔法的任何方法-此方法将调整其返回类型,使其成为调用者希望的任何类型。鉴于
class Parent
以及class Joe extends Parent
以及class Jane extends Parent
,则这将起作用:你怎么能
getConfig()
知道它的返回类型实际上是Joe
? 没有。它会适应你想要的样子。这是一件坏事-因为如果你看代码,它实际上不是这样工作的:
以及:
只会编译。当然,在运行时爆炸
getConfig()
方法最终生成Jane
,它不能赋给joe类型的变量,这意味着没有简单的“这是如何修复代码”的答案,因为你所写的是毫无意义/不可能的。你大概打算做两件事之一:
或者:
当然,也许吧
c
是代表joe的类示例,但也可能是jane。您的api所能做的唯一承诺是,无论类示例是什么,它所做的任何示例都将可赋值给parent类型的变量。毕竟,Parent p = new Joe();
是有效的Parent p = new Jane();
.没有必要涉及泛型。泛型是更高的一个“元”级别:它将类型系统本身转化为一种编程语言,在这里您不需要这样做。
您可能需要的另一种选择是链接
getConfig()
方法来指定此对象的类示例的特定类型:请注意,在这段代码中,完全不需要强制转换,上面的代码是按编写的那样编译的。泛型也很有用,因为t出现在两个地方:两个
Class<T>
构造函数中的参数,以及T
的返回类型getConfig
方法(在class Parent<T>
不算数,那不是在使用它,那是在定义它的存在)。