如何在运行时获得泛型类型? [英] How to get the generic type at runtime?

查看:116
本文介绍了如何在运行时获得泛型类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码:
ExecutorImp扩展AbstractExecutor,它抽取执行者的相同执行逻辑(ExecutorImp是一种情况),当调用ExecutorImp的execute()方法时,它将调用超类型的方法,但超类型(AbstractExcutor)应该知道另一个类绑定到实现者(在这个例子中,它是User类):

This is my code: The ExecutorImp extends AbstractExecutor which extract the same execute logics of its implementers(ExecutorImp is one case),when calling the execute() method of ExecutorImp, it will call the method in its supertype,but the supertype (the AbstractExcutor) should know another class binding to the implementer(in the example, it is the User class):

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

abstract class AbstractExecutor<E> {
    public void execute() throws Exception {
        ArrayList<E> list = new ArrayList<E>();
        // here I want to get the real type of 'E'
        Class cl = this.getClass().getTypeParameters()[0].getGenericDeclaration().getClass();
        Object o = cl.getConstructor(String.class).newInstance("Gate");
        list.add((E) o);
        System.out.println(format(list));
    }
    public abstract String format(ArrayList<E> list);
    public abstract String getType();
}

public class ExectorImp<E> extends AbstractExecutor<User> {
    @Override
    public String getType() {
        return "user";
    }
    @Override
    public String format(ArrayList<User> list) {
        StringBuffer sb = new StringBuffer();
        for (User u : list) {
            sb.append(u.toString() + " ");
        }
        return sb.toString();
    }
    public static void main(String[] args) throws Exception {
        new ExectorImp().execute();
    }
}
class User {
    String name;
    public User(String name) {
        this.name = name;
    }
}

那么,我的代码有什么问题?

SO, what is the problem with my codes?

推荐答案

这里有一些困惑。由于类型擦除,您无法从运行时参数化类型获取类型信息,如:

There's some confusion here. Due to type erasure you can't get type information from the runtime parameterized type like:

Class<E> cls = E.getClass(); // Error.
E e = new E(); // Error.

但是,您可以从类,字段和方法声明中获取编译时参数化类型信息ParameterizedType#getActualTypeArguments()

However, you can obtain compiletime parameterized type information from class, field and method declaration by ParameterizedType#getActualTypeArguments().

abstract class AbstractExecutor<E> {

    public void execute() throws Exception {
        List<E> list = new ArrayList<E>();
        Class<E> cls = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        E e = cls.getConstructor(String.class).newInstance("Gate");
        list.add(e);
        System.out.println(format(list));
    }

    // ...
}



< hr>

更新:关于是否推荐使用这种方法,尽管这可以起作用,但对于类声明中的小改动。你作为开发者应该正确记录它。作为一个完全不同的选择,您可以使用多态。


Update: as to whether this is recommended or not, although this will work, this is sensitive to runtime problems whenever minor changes in the class declaration occur. You as developer should document it properly. As a completely different alternative, you can make use of polymorphism.

abstract class AbstractExecutor<E> {

    public void execute() throws Exception {
        List<E> list = new ArrayList<E>();
        E e = create("Gate");
        list.add(e);
        System.out.println(format(list));
    }

    public abstract E create(String name);

    // ...
}

并执行 UserExecutor

class UserExecutor extends AbstractExecutor<User> {

    @Override
    public User create(String name) {
        return new User(name);
    }

    // ...
}

这篇关于如何在运行时获得泛型类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆