<t> getInstance(最终的Class <t>类型)为什么不为两个Class <t>?</t> </t> </t>

时间:2015-01-13 19:17:28

标签: java class generics

所以,我正在深入研究Java并对这种类型参数的使用感到好奇。

<T>T getInstance

然后是arg

Class<T> type

我在这里有点困惑,因为如果我们需要一个返回类型,由T表示那么为什么arg不是相同的...例如

private static String getInstance(String arg)

所以我认为它会是

private static Class<T> getInstance(final Class<T> type)

所以,我很困惑为什么返回类型与参数

的表达式不同

5 个答案:

答案 0 :(得分:7)

不需要使返回类型与参数类型相同,也不需要任何规则来指示。

当方法定义为

private static <T> T getInstance(final Class<T> type)

这意味着返回对象的类型为T,而传递给该方法的参数是参数化为java.lang.Class的通用T类型的实例。

这意味着可以按如下方式调用该方法:

String string = getInstance(String.class);

因此,此方法采用类型为Class的实例,并返回与此Class参数对应的类型的对象。

另一方面,当方法定义为

private static <T> T getInstance(final T type)

然后你被迫传递T类型的对象以获取实例。想象一下,它将被调用如下:

String string = getInstance("a");

请注意String类型的对象“a”与类型String.class的{​​{1}}的完全不同。

答案 1 :(得分:4)

TClass<T>完全不同。

第一个说,“某种类型的物体,T”。第二个说,“java.lang.Class类型的对象,它代表某种类型T的类。”

换句话说,这里有两种可能的实现:

Class<T> getInstance(Class<T> type) {
    return type;
}

T getInstance(Class<T> type) {
    return type.newInstance();
}

例如,如果TString,则其中第一个将返回String.class,第二个将返回空字符串""

答案 2 :(得分:3)

想一想该方法的作用:它从instance返回Class

用法:

final String string = getInstance(String.class);

那么回报是什么 - 它是String。问题是什么 - 它是class String,由Class<String>表示。

因此方法签名变为:

String getInstance(Class<String> string);

String标准化为T会在您的问题中为您提供签名。

答案 3 :(得分:2)

当你必须在类型擦除的泛型方法中创建一个对象时,这是Java已经实现的一个技巧来解决鸡与蛋的问题。

Class<T>是通用的,因此您可以以类型安全的方式调用getInstance。如果<T> Class中没有T,您的所有Object getInstance() {...} 都会被删除,请留下

T

并且无法获得已被删除的类Class<T>的引用。

传递Object getInstance(Class cl) {...} 解决了这个问题,因为现在删除的签名如下所示:

Class

虽然类型再次被删除,但现在你有一个T对象,它可以用作&#34;工厂&#34;制作班级Class<T>的新对象。 {{1}}在其创建的类型上是通用的这一事实允许Java编译器执行类型检查,确保编译器隐式插入的强制转换将在运行时成功。

答案 4 :(得分:2)

您应该将与其实例区分开来。它可能很棘手,因为在Java类中也是对象,因此它们也有一个类(类的类!)。说:

class Foo { ... }
  • Foo的一个实例有类型Foo;
  • Foo本身是另一个类的(唯一)实例,正好是Class<Foo>

所以在上面的声明中,从左到右:

  • <T>是通用参数,使该方法成为通用方法;
  • T是返回类型:该方法返回类T的实例;
  • getInstance是方法的名称;
  • Class<T>表示您必须将类T的(仅)实例作为参数传递,该类本身具有类Class<Foo>

您可以通过隐式静态字段Foo.class访问此单例实例。每个声明的类都有它,虽然你不会在源代码中找到它(棘手的反射问题)。

最后,为什么Class是通用的?好吧,有类似的东西:

package java.lang;

public final class Class<T> {
   public static T newInstance();
   ...
}

所以Foo.class.newInstance()返回FooBaz.class.newInstance()返回Baz,依此类推。干净,不是吗?