当前位置: 首页 > 面试题库 >

如何在运行时获取泛型?

养星汉
2023-03-14
问题内容

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

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;
    }
}

所以,我的代码有什么问题?


问题答案:

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

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

但是,您可以通过从类,字段和方法声明中获取编译时参数化类型信息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));
    }

    // ...
}

更新
:关于是否建议这样做,尽管这将起作用,但是只要在类声明中进行较小的更改,这对运行时问题就很敏感。作为开发人员,您应该正确记录它。作为完全不同的替代方法,可以利用多态性。

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);
    }

    // ...
}


 类似资料:
  • 问题内容: 我们有以下课程 和这个 现在,我需要在运行时知道is是否为 。由于这是jpa自动处理的,因此我无法获取此值。 我们正在调用一个带有as参数的方法,我想避免使用它来检查它是什么类型。如果我可以做些类似的事情会更酷 问题答案: 您可以将鉴别符映射为只读属性:

  • 问题内容: 在运行时很容易获得方法, 但是在运行时 如何获得方法? 如以下示例 我们的类,其中包括我们的目标方法 具有主要方法的班级 问题答案: 您不能:该文件不包含注释。 一种“解决方案”是在构建程序时将Javadoc生成为HTML,并从类名和方法名构建URL。您还可以使用doclet API 以比HTML更合适的格式生成javadoc 。

  • 如何在运行Tomcat时获取包版本? 我尝试getClass().getPackage().GetImplementationVersion(),但这总是返回。我想这是因为我的war还没有打包,而Tomcat执行了.classes(又名分解的war)。存在于终战中,但不存在于文件夹中 java.lang.Package 相关的是在运行时获取Maven工件版本 更新。之前我已经添加了war构建的配置

  • 问题内容: 在Hibernate 3.2中如何在运行时设置获取类型? 如果有可能在运行时更改获取类型(“懒惰/渴望”)。因此,如果已经定义了获取模式,即hibernate.mapping文件中的“选择/连接”,是否有任何影响? 问题答案: 您可以用来指定要初始化的特定集合。 例如 在这里查看更多

  • 问题内容: 我想检查代码是否正在运行,以便可以进行一些配置。 有功能吗?喜欢: runtime.IsBeingTested() 问题答案: 只需指定您在test的中运行测试即可。例如,在pkg.go中: 在pkg_test.go中: 该技术不仅可以与s 一起使用,还可以与任何数据或函数一起使用。如果您的软件包中有一些变量(在您的情况下为配置变量),则可以在中将其覆盖。

  • 问题内容: 好的,因此,我正在设置自己的XML序列化(我知道那里还有其他东西,甚至Java中内置了一些东西,但是我自己学习来做,因为可以使用它非常棒)。我已经序列化了。我目前正在进行反序列化(读取XML文件并基于文件中的数据组装对象),并且在设置通用类型时遇到问题。经过广泛研究,我弄清楚了如何获取类的泛型类型,以便在序列化时可以编写它们,但是我不知道如何执行此操作: 我已经在C#中看到了一些答案,