【问题标题】:Is it possible to obtain an instance of Class<SomeGenericClass<SomeType>>是否可以获得 Class<SomeGenericClass<SomeType>> 的实例
【发布时间】:2012-05-25 15:00:04
【问题描述】:

是否可以获取Class&lt;SomeGenericClass&lt;SomeType&gt;&gt;的实例?

例如,Class&lt;ArrayList&lt;String&gt;&gt; 的实例没有实例化 ArrayList&lt;String&gt; 的实例。

 

@SuppressWarnings("unchecked")
public static <T> T castToGeneric(Object objectToCast, T typeInferrenceClass) {
    return (T)objectToCast;
}

// usage

Object someObject = null /* initialised elsewhere */;
List<String> listOfStrings = castToGeneric(someObject, new ArrayList<String>());

// I want to avoid having to create - new ArrayList<String>();

我知道这段代码很难看,我不应该这样做。但我们就在我们所在的地方......

【问题讨论】:

  • 明确一点,你得到的是Class的一个实例,剩下的只是编译器的注解。
  • @MarkoTopolnik 是的 - 我想要一个类的实例
  • @gasan 你试过编译你输入的内容吗?
  • List 是一个接口,而不是一个类。例如,您只能从 ArrayList 中获取 Class。
  • @RobertKovačević 错误。 Java 中的每种类型都有其 Class 实例,甚至是 int.class

标签: java generics


【解决方案1】:

我找到了解决您问题的方法:

@SuppressWarnings("unchecked")
public static <T> T castToGeneric(Object objectToCast) {
    return (T)objectToCast;
}

// usage

Object someObject = null /* initialised elsewhere */;
Class<ArrayList<String>> listOfStrings = <Class<ArrayList<String>>>castToGeneric(someObject);

所以不是将类型作为参数传递,而是将其作为类型参数传递。

【讨论】:

    【解决方案2】:

    如果要实例化Class&lt;SomeGenericClass&lt;SomeType&gt;&gt;

    Class<List<Object>> list = (Class<List<Object>>)(Class<?>)List.class;
    
    Type genericclass = new ArrayList<Object>() {}.getClass().getGenericSuperclass();
    

    【讨论】:

    • 请说明如何创建传递给方法的“theClass”参数。当 T 是 List?
    • OP 特别要求无需实例化的解决方案,并且您的第一行会发出未经检查的强制转换警告。我有点认为 OP 已经意识到半途而废的解决方案并想要一个干净的解决方案。
    • 由于类型擦除,永远不可能有一个干净的解决方案。真的没有Class&lt;GenericClass&lt;SomeType&gt;&gt; 这样的东西;你能做的最好的事情就是给它一个Class&lt;GenericClass&gt;
    • @LouisWasserman 这与类型擦除有什么关系? Class&lt;List&lt;String&gt;&gt; 是合法类型,例如,newInstance 的返回类型对于此类 var 是 List&lt;String&gt;。唯一的问题是如何将 List.class 文字转换为它。
    • A Class 是一种类型的运行时表示,在运行时,没有泛型类型。任何Class&lt;List&lt;String&gt;&gt;必须满足listStringClass.equals(List.class)。参见例如stackoverflow.com/questions/71585/…
    【解决方案3】:

    由于Java泛型中的类型擦除,对“List”实例调用“getClass”的结果会丢失类型参数“String”,换句话说,可能无法获取“Class>”。但你可以在 Scala 中做到这一点:

    scala> List("foo", "bar").getClass
    res0: java.lang.Class[_ <: List[java.lang.String]] = class scala.collection.immutable.$colon$colon
    

    【讨论】:

    • 但是说OP想要分配给一个变量Class&lt;List&lt;String&gt;&gt; c
    【解决方案4】:

    这满足您的“无实例”标准,编译并运行正常:

    Class<ArrayList<String>> c =
        (Class<ArrayList<String>>) Class.forName("java.util.ArrayList");
    

    由于类型擦除,这可以工作:在运行时,ArrayList&lt;String&gt; 只是 ArrayList,而且Class&lt;ArrayList&lt;String&gt;&gt; 只是 Class

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      • 2013-02-24
      • 1970-01-01
      • 2011-03-06
      相关资源
      最近更新 更多