Class ClassView<X>

  • Type Parameters:
    X - program type that this view represents.

    public final class ClassView<X>
    extends TypeView
    TypeView that handles Class.
    • Field Detail

      • type

        protected final T extends Type type
    • Method Detail

      • of

        public static <X> ClassView<X> of​(Class<X> clazz)
        Creates view over provided type.
        Type Parameters:
        X - actual type represented by this class
        Parameters:
        clazz - construct to wrap
        Returns:
        view wrapping specified type
      • adjustWildcards

        public <S extends XClassView<S> adjustWildcards()
        Allows cast-less conversion from raw class to either generic form, or parametrized class.

        This function exists, because creating ClassView from class literal will produce view with raw type as argument. When provided literal is a generic class, produced type should parameterized with unbounded wildcards, but isn't. This method allows adjusting the type easily.

        Example:

         ClassView<List> rawView = ClassView.of(List.class);
         ClassView<List<?>> genericView = rawView.adjustWildcards();
         

        This method is equivalent to just casting to parameterized class with wildcards, but without unchecked warning.

        WARNING: This method can be used to cast to inheriting types, i.e. ClassView<ArrayList<Number>> in previous example. If you are concerned that this might be the case, avoid this method, its only for convenience.

        Type Parameters:
        S - parameterized type to cast to
        Returns:
        casted class view
      • erasure

        public Class<X> erasure()
        Description copied from class: TypeView
        Finds exact class that would be erasure of wrapped type.

        This method is implemented according to JSL section 4.6 with following extensions:

        • Erasure of wildcard type is erasure of its leftmost upper bound, or Object if there isn't one

        These extensions are needed, because these types are cannot be used in declaration, but can be obtained by reflections.

        Specified by:
        erasure in class TypeView
        Returns:
        erasure of wrapped type
      • parameters

        public List<TypeVariableView<Class<X>>> parameters()
        Extracts type variables that class declares.

        This is empty if class is non-generic.

        Returns:
        variables declared by class
      • asParameterized

        public ParameterizedTypeView asParameterized()
        Converts wrapped class to ParameterizedType.

        This always can be done, but the results might not be expected. Non-generic classes are be treated as generic class with zero type parameters. Generic classes are represented as parametrized type with the raw type being wrapped class and type arguments are copied from this class type parameters.

        Resulting parameterized type is purely synthetic - it can never be actually declared or used in code.

        Specified by:
        asParameterized in class TypeView
        Returns:
        this view converted to view for parameterized type
      • asClass

        @Deprecated
        public ClassView<?> asClass()
        Deprecated.
        the type system already knows this is a class, and this call does not change the type
        Try to cast or convert wrapped type to Class.

        This method is useful if you know that underlying type is Class, then this is just a casting.

        This can also be done for parameterized types with no actual substitutions and array classes represented by ArrayTypeView

        Specified by:
        asClass in class TypeView
        Returns:
        this, as this is already class view
      • asArray

        public ArrayTypeView asArray()
                              throws IllegalStateException
        Try to cast/convert wrapped type to GenericArrayType.

        This method is useful if you know that underlying type is GenericArrayType, then this is just a casting.

        This can also be done for parameterized types with no actual substitutions that represetn array class, and class view that has array class.

        This method only works if wrapped class represents an array.

        Specified by:
        asArray in class TypeView
        Returns:
        this view casted/converted to view for array
        Throws:
        IllegalStateException - when this view wraps a class that's not an array
      • isSubTypeOf

        public boolean isSubTypeOf​(TypeView other)
        Description copied from class: TypeView
        Tests if type wrapped in this view is subtype of the provided one.

        This method tries to adhere to the spirit of subtyping: it answers the question: Having reference of type T, can value of type S be always assigned to it?

        Subtyping is precisely defined for types that can be declared in source, but there are more types that can be constructed or extracted via reflections. This method follows JLS section 4.10 for every aspect it declares, but also defines sensible rule for subtyping wildcards: wildcard is a supertype of its lower bounds, i.e. ? super CharStream is supertype of CharStream and

        Specified by:
        isSubTypeOf in class TypeView
        Parameters:
        other - type to test subtype relation against
        Returns:
        true if this type is subtype of provided argument
      • visit

        public <T> T visit​(TypeView.Visitor<T> visitor)
        Description copied from class: TypeView
        Visitor patter method dispatching method.

        This method calls specific method on provided visitor, depending on actual implementation of this type.

        It will return whatever the method returns.

        Specified by:
        visit in class TypeView
        Type Parameters:
        T - type returned by visitor method
        Parameters:
        visitor - method target
        Returns:
        same result as visitors method.
      • resolve

        public ParameterizedTypeView resolve​(Type other)
        Description copied from class: TypeView
        Create view that has variable substitutions copied from provided.

        See documentation on TypeView.resolve(TypeView) for details.

        Overrides:
        resolve in class TypeView
        Parameters:
        other - type to copy substitutions from
        Returns:
        TypeView that uses substitutions from provided type
      • resolve

        public ParameterizedTypeView resolve​(TypeView other)
        Description copied from class: TypeView
        Create view that has variable substitutions copied from provided.

        This method creates type that has any variable substituted by substitutions used in other.

        Substitutions are found recursively. They can be only directly found in parameterized types, as arguments, but these parameterized types can be found in components of some containing type. For example, wildcard might use parameterized type as a bound, and this parameterized type might have substitution for specific variable.

        This method can be used to find what the signature of field or method looks like in some specific type. For example: lets say that there's a generic class class Example<T> that declares field protected List<T> elements. It's descendant class, declared class ExtendedExample extends Example<String> inherits field elements. In this case no conventional method will extract actual field type, List<String>:

        But this can be resolved using this method: TypeView.ofTypeOf(Example.class.getDeclaredField("elements")).resolve(ExampleExtension.class) will wrap List<String>, because variable substitution T -> String is used.
        Overrides:
        resolve in class TypeView
        Parameters:
        other - type to copy substitutions from
        Returns:
        TypeView that uses substitutions from provided type
      • unwrap

        public final T unwrap()
        Description copied from class: TypeView
        Extracts native type from this view.

        This is inverse operation from TypeView.of(Type)

        Specified by:
        unwrap in class TypeView
        Returns:
        type that this view was for
      • hashCode

        public int hashCode()
        Overrides:
        hashCode in class Object