user3089214
user3089214

Reputation: 267

How to pass bounded generic type parameter class as argument

how do you get class name of type parameter object?

Example: if function is

public <T extends Base> void convert(final T arg) {}
public <T> void method2(Class<T> typeParamClass) {}

How do i pass arg as Class<T> to method 2?

Error message when i try to pass arg.getClass()

Real Code Snippet

static <T> byte[] method2(T object, final Class<T> typeParameterClass) throws SerializationException {
}


static <T> T method3(final byte[] serializedObject, final Class<T> typeParameterClass) throws SerializationException {
        return (T) serializer.deserialize(typeParameterClass, Buffers.toBuffer(serializedObject));
    }
}

public static <T> T clone(final T object) {
    return method3(method2(object, object.getClass()), object.getClass());
}

enter image description here

Upvotes: 1

Views: 6015

Answers (2)

Isabaellchen
Isabaellchen

Reputation: 98

As mentioned in the answer from Andrew, the problem is the type erasure.

You are working with generics, getClass on T yields Class<?>, not Class<T>.

However, since we know that the type of T will always be Class<T>, you can cast object.getClass to Class<T>, so you don't have to alter the method signature with redundant parameters.

So you could write:

public static <T> T clone(final T object) {
    @SuppressWarnings("unchecked") // The type of 'object' will always be 'T'
    Class<T> typeClass = (Class<T>) object.getClass();

    return method3(method2(object, typeClass), typeClass);
}

Upvotes: 1

Andrew
Andrew

Reputation: 49646

public <T> void method2(Class<T> typeParamClass)

If you make the second method generic, you will be able to invoke that like

public <T extends Base> void convert(final T arg) {
    method2(arg.getClass());
}

There are no restrictions for T in the method2 (T extends Object), so you are free to pass any T (including T extends Base).

As Sotirios Delimanolis noted, T is really meaningless here and the method can be defined simply:

public void method2(Class<?> typeParamClass)

UPDATE:

method2(object, object.getClass())
                       ^^^

The main issue here is that getClass() is a virtual method, returns a runtime type of an instance. It can not guarantee to return a Class<T> from the given T, but ? extends T it can. To make it compiles, you have to change the signature to:

method2(T object, final Class<? extends T> typeParameterClass)
                              ^^^

Upvotes: 4

Related Questions