Erasure Type Workaround in Java

So the group I'm working with has reduced the amount of code we need to enter for certain things. In this case, the Spring webpage that displays the list using DisplayTag libraries. The way this is done is a class using generics extending the object Controller, and then subclassing this for each page it should work on.

This controller displays SystemErrorReportand determines the type SystemErrorReportCommand.

public class SystemErrorReportController extends
    GenericSearchAndSelectController<SystemErrorReportCommand> {

The problem is that SystemErrorReportCommandbeing passed as a type needs to be manually declared in its constructor, for example:

public SystemErrorReportCommand()
{
    super(SystemErrorReport.class);
}

Then the command object is passed to what its explicit type must know. Without manually specifying it somewhere, it returns as GenericCommand, another class of ours, because the bit SystemErrorReportCommandis lost after compilation.

I am not happy with this because it seems that we can automate more to reduce the developer error. Is there a more elegant way to do this, or am I sticking to this because of erasing styles?

+3
source share
3 answers

Perhaps you could use something like a Javassist to execute some metaprograms.

It is used at Tapestry for this purpose, see this article .

+1
source

, , , .

, : TypeTokens

+4

, , : , ( ) .

, SystemErrorReportCommand SystemErrorReportController,

((ParameterizedType) SystemErrorReportController.class.getGenericSuperType()).getActualTypeArguments[0];

, . , api, , , - .

, :

public abstract class Test<T extends Number> extends ArrayList<Long> implements Comparable<String>, List<Long>{
    public List<String> field;
    public abstract <M> M method(List<T> arg);

    public static void main(String... args) throws Exception {
        TypeVariable<Class<Test>> t = Test.class.getTypeParameters()[0];
        Class<?> upperBound = (Class<?>) t.getBounds()[0];


        System.out.println("Test<" + t + " extends " + upperBound.getName() + ">");
        System.out.println("extends " + Test.class.getGenericSuperclass());
        System.out.println("implements " + Arrays.toString(Test.class.getGenericInterfaces()));
        System.out.println("{");
        System.out.println(Test.class.getMethods()[1].toGenericString());
        System.out.println(Test.class.getFields()[0].toGenericString());
        System.out.println("}");
    }
}

:

Test<T extends java.lang.Number>
extends java.util.ArrayList<java.lang.Long>
implements [java.lang.Comparable<java.lang.String>, java.util.List<java.lang.Long>]
{
public abstract <M> M Test.method(java.util.List<T>)
public java.util.List<java.lang.String> Test.field
}

I am using the method toGenericString(). However, this is just a great way to print! There is no need to disassemble, that String: reflection api provides all the necessary information, for example Field.getGenericType(), Method.getArgumentTypes...

+3
source

Source: https://habr.com/ru/post/1719103/


All Articles