Explanation for a collapsed type declaration. What is class <? extends the class <? does extends Actor> []> really mean?

Imagine we have this class.

public class Actor {...}

      

And then we have a method that needs a parameter, which is a type:

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

Is it possible? I couldn't decipher it.

+3


source to share


2 answers


Yes. Let the work from the inside:

  • ? extends Actor

    means something that is Actor

    or any subtypes Actor

    .
  • Class<? extends Actor>[]

    means an array of objects Class<T>

    , where each object represents a class that is either Actor

    a subtype Actor

    .
  • Class<? extends Class<? extends Actor>[]>

    represents a class of an array of objects of a class where each object has Actor

    either one or one of its subtypes. *

Here's an example that should make it clearer:



//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();

      

It is important to note that this giant expression does not represent a class that itself extends an array of objects Class<? extends Actor>

. Instead, it represents an array of objects classClass<? extends Actor>

.

* Technically, you can't create an array of a generic type , which means it's Class<? extends Actor>[]

really simple Class[]

. So in the end you just end up with Class<Class[]>

, which is a class that represents an array of objects Class

(i.e. just Class[].class

).

+6


source


Interesting. Let this type have a shorter name "CCA"

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

      

extension of the first template,

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

      

to subtype an array, we must have

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

      

therefore

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

      

If we consider the fact that Class

final

, then A must be



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

      

therefore

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

      

Meaning, CCA covers class objects representing the type arrays Class<Actor>[]

, Class<BadActor>[]

, Class<? extends BadActor>[]

etc.

On the other hand ... we know it T

cannot be an arbitrary type in Class<T>

. While syntactically Class<List<String>>

valid, List<String>

there really isn't a class for; there is only a class List

; therefore only makes sense Class<List>

.

And ... for arrays, but there are types of compile-time as List<String>[]

, List<Integer>[]

there is only one class runtime appropriate List[]

.

Hence, CCA is really simple Class<Class[]>

; there is exactly one object for this type - Class[].class

that is, a class that represents the type of the array Class[]

.

Given an object of type CCA, there is nothing you can do about it. I am curious to know where you saw this type and what the actual use case is.

+3


source







All Articles