Adam Paynter
Adam Paynter

Reputation: 46938

Is there an alternative to Class.isAssignableFrom that works with Type objects?

In Java, Class has an isAssignableFrom method defined as follows:

public boolean isAssignableFrom(Class<?> cls)

Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter. It returns true if so; otherwise it returns false. If this Class object represents a primitive type, this method returns true if the specified Class parameter is exactly this Class object; otherwise it returns false.

Specifically, this method tests whether the type represented by the specified Class parameter can be converted to the type represented by this Class object via an identity conversion or via a widening reference conversion. See The Java Language Specification, sections 5.1.1 and 5.1.4 , for details.

Parameters:

cls - the Class object to be checked

Returns:

the boolean value indicating whether objects of the type cls can be assigned to objects of this class

Class implements the Type interface. Is there an equivalent isAssignableFrom method that works on Types instead of just Classes? For example, is there a method that determines if a variable of type List<String> (which would be represented via an instance of ParameterizedType) can be assigned to a variable of type List<? extends Object>?

Upvotes: 8

Views: 5362

Answers (4)

john16384
john16384

Reputation: 8064

There is TypeUtils.isAssignable(Type, Type) in Apache Commons Lang3

Upvotes: 0

Gunnar
Gunnar

Reputation: 19020

Guava's TypeToken utility provides that functionality. Your query could be answered like this:

// represents List<String>
ParameterizedType stringList = ...; 

// represents List<? extends Object>
TypeToken objectList = new TypeToken<List<? extends Object>>(){};

boolean isAssignable = objectList.isAssignableFrom( stringList );

Upvotes: 2

Dims
Dims

Reputation: 51229

You can cast between any List<...>-s, the protection is weaker than normally.

Try this

    List<String> a = new Vector<String>();
    List<Integer> b = new Vector<Integer>();
    Integer i = new Integer(0);

    b.add(2);

    a = (List<String>) (Object) b;

    System.out.println((Object)a.get(0));

no exceptions will be thrown.

This is because generics are only compile time notion.

If you write

           System.out.println(a.get(0));

you will get ClassCastException because println function version determined at compile time will be println(String arg).

Ah, so the answer to the question: it should be incorrect to have such an alternative.

Upvotes: 0

pholser
pholser

Reputation: 4937

Have a look at javaRuntype -- I've found it useful. It can produce representations of types from instances of java.lang.reflect.Type, and test assignability between them.

Upvotes: 2

Related Questions