3

If I have the following:

public abstract class Parameterized<T> {
  protected abstract String foo();
}

Is it possible to do something like:

DynamicType.Unloaded<Parameterized<MyClass>> subclassed = new ByteBuddy()
    .subclass(Parameterized.class)... //assign MyClass.java to T?

Or is it only possible to do:

DynamicType.Unloaded<Parameterized> subclassed = new ByteBuddy()
    .subclass(Parameterized.class).make();
Michael
  • 41,989
  • 11
  • 82
  • 128
MMP
  • 546
  • 2
  • 5
  • 19

2 Answers2

4

Only type information of instances is erased; not on references. Depending on usecase it might provide some benefits to actually extend with the correct parameters (instead of extending the raw type).

Thats how you do it with ByteBuddy:

Class<?> subclass = new ByteBuddy()
  .subclass(TypeDescription.Generic.Builder.parameterizedType(Parameterized.class, MyClass.class).build())
  .make()
  .load(Parameterized.class.getClassLoader())
  .getLoaded();

One way of using/extracting the type parameter at runtime would be:

Paramerized<MyClass> instance = (Paramerized<MyClass>) subclass.getConstructor().newInstance();
if (instance.getClass() instanceof ParameterizedType) {
    ParameterizedType para = (ParameterizedType) instance.getClass().getGenericSuperclass();
    System.out.println(para.getActualTypeArguments()[0]);
}
k5_
  • 5,450
  • 2
  • 19
  • 27
-2

Because generics in Java are implemented using type erasure, Parameterized<MyClass> only really exists at compile time. At runtime there is only Parameterized.

Therefore there are only a few uses for this. Please see K5_'s answer.

Community
  • 1
  • 1
Michael
  • 41,989
  • 11
  • 82
  • 128
  • There are not many usages outside of framework development, but it is possible. – k5_ May 19 '17 at 12:34
  • For example. Hibernate would need to know that a list contains `YourBean` instances in order to trigger the correct database query when loading your collection. This makes runtime generics useful. – Rafael Winterhalter May 22 '17 at 07:10