2

What is the difference between passing in generic parameter some generic class with and without his generic parameter?

Example:

Simple Generic class:

public class Foo<T> { /*...*/ }

Simple class that extend simple generic class setting the generic parameter to some irrelevant type:

public class FooFoo extends Foo<Type1> { /*...*/ }

Another generic class

public class Bar<T> extends FooFoo { /*...*/ }

Our base class that as generic parameter need something that extends class Foo

public class TestFooClass<T extends Foo<?>> { /*...*/ }

And the question what is the deference between this two parameters

public class BarTestOne extends TestFooClass<Bar> { /*...*/ }

public class BarTestTwo extends TestFooClass<Bar<?>> { /*...*/ }

Problem

Class<T> class = (Class<T>) ((Foo)getClass().getGenericSuperclass()).getActualTypeArguments()[0];

In the first case code works in the second doesn't.

1

2 Answers 2

3

It looks like you are trying to determine the actual type that the TestFooClass is parameterized with?

In that context, the difference between using generic class with and without its generic parameter is that getActualTypeArguments()[0] will:

  1. In the first case provide an instance of Class representing the raw type
  2. In the second case provide an instance of ParameterizedType (thus one may get ClassCastException). If you call getRawType() on that ParameterizedType, you will get Class representing the raw type.

This:

BarTestOne one = new BarTestOne();
BarTestTwo two = new BarTestTwo();

Class<?> clazz1 = (Class<?>) ((ParameterizedType) one.getClass().getGenericSuperclass()).getActualTypeArguments()[0];       
Class<?> clazz2 = (Class<?>) ((ParameterizedType) ((ParameterizedType) two.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getRawType();

System.out.println(clazz1.equals(clazz2));

This will return true.

Alas, any deeper answer is beyond my knowledge of generics.

Sign up to request clarification or add additional context in comments.

Comments

0

Bar means Bar<Object> and Bar<?> doesn't. For example, if you have a List, you can add to it, if you have a List<?> you can't, because the compiler doesn't know if your object is compatible with the "actual generic type" of the object.

As for the reflection code, I don't know. It says getClass(), which depends on the object you call it on; in this case the object is obviously this... From where is this code called?

2 Comments

Yes, but in this case the Bar<Object> or Bar<?> have the same impact.
Actually Bar is the raw supertype of Bar<?> and Bar<Object> is a subtype of Bar<?>.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.