【问题标题】:Explanation for convoluted generic-type declaration. What does Class<? extends Class<? extends Actor>[]> actually mean?复杂的泛型类型声明的解释。什么是类<?扩展类<? extends Actor>[]> 究竟是什么意思?
【发布时间】:2015-09-25 14:00:28
【问题描述】:

想象一下我们有这个类。

public class Actor {...}

然后我们有一个方法需要一个参数类型:

Class&lt;? extends Class&lt;? extends Actor&gt;[]&gt;

这甚至可能吗?我无法破译它。

【问题讨论】:

  • 可能是错的,但不要认为你可以扩展一个类 <...>[ ] 因为数组并不是一个真正的类。
  • 你指的当然是java.lang.Class,不是吗?

标签: java class generics types


【解决方案1】:

是的。让我们由内而外地工作:

  • ? extends Actor 表示 ActorActor 的任何子类型。
  • Class&lt;? extends Actor&gt;[] 表示Class&lt;T&gt; 对象的数组,其中每个对象代表一个类,该类要么是Actor,要么是Actor 的子类型。
  • Class&lt;? extends Class&lt;? extends Actor&gt;[]&gt; 表示类对象数组中的类,其中每个对象要么是Actor,要么是它的一个子类型。*

这里有一个例子应该让它更清楚一点:

//actorClass is a Class<T> object that represents Actor.class 
//or any of its subtypes
Class<? extends Actor> actorClass = Actor.class;

//classArray is an array of Class<? extends Actor> objects, and so its type is 
//Class<? extends Actor>[]
//You will get a warning about an unsafe cast here because you
//cannot really create an array of generic type, which means the
//RHS type is just `Class[]`.
Class<? extends Actor>[] classArray = new Class[] {
    actorClass, actorClass, actorClass
}; 

//Now we get the class of the array itself, which matches the convoluted
//expression you saw.
Class<? extends Class<? extends Actor>[]> classArrayClass = classArray.getClass();

这里要注意的重要一点是,这个巨大的表达式并不代表一个类,它本身扩展了Class&lt;? extends Actor&gt; 对象的数组。相反,它表示Class&lt;? extends Actor&gt; 对象的数组的类

* 从技术上讲,you can't create an array of a generic type,这意味着Class&lt;? extends Actor&gt;[] 真的只是Class[]。所以最终你会得到Class&lt;Class[]&gt;,这是代表Class对象数组的类(即,只是Class[].class)。

【讨论】:

    【解决方案2】:

    有趣。让我们给这个类型一个更短的名字“CCA”

    CCA = Class<? extends Class<? extends Actor>[]>
    

    扩展第一个通配符,

    CCA = all Class<T> where T <: Class<? extends Actor>[]
    

    对于数组子类型,我们必须有

    T = A[] where A <: Class<? extends Actor>
    

    因此

    CCA = all Class<A[]> where A <: Class<? extends Actor>
    

    如果我们探究Classfinal 的事实,那么A 一定是

    A = Class<C> or Class<? extends C> where C <: Actor
    

    因此

    CCA = all Class<Class<C>[]> and  Class<Class<? extends C>[]> where C<:Actor
    

    意思是,CCA 涵盖了表示数组的类对象,如Class&lt;Actor&gt;[]Class&lt;BadActor&gt;[]Class&lt;? extends BadActor&gt;[]

    另一方面 ...我们知道T不能是Class&lt;T&gt;中的任意类型。虽然语法上Class&lt;List&lt;String&gt;&gt; 是有效的,但List&lt;String&gt; 确实没有类;只有类List;因此只有Class&lt;List&gt; 有意义。

    而且...对于数组,即使有List&lt;String&gt;[]List&lt;Integer&gt;[]这样的编译时类型,也只有一个运行时类,对应List[]

    因此,CCA 真的只是Class&lt;Class[]&gt;;这种类型只有一个对象 - Class[].class,即表示数组类型 Class[] 的类。

    给定一个 CCA 类型的对象,你可以用它做任何有趣的事情。我很想知道您在哪里看到过这种类型,以及实际用例是什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 2012-03-18
      • 1970-01-01
      • 2022-01-02
      相关资源
      最近更新 更多