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

无法从Guava解析通用参数TypeToken

薛博艺
2023-03-14
问题内容

我正在开发一个用于为Selenium测试框架构建通用菜单的框架,并且我一直在使用Guava
TypeToken来解析通用参数的类型,但是现在我遇到了一个问题,其中类型令牌无法解析参数:

我有一个生成菜单选项的构建器abstract基础class

public abstract class AbstractMenuOptionBuilder<O extends IClickable>  {

    protected final TypeToken<AbstractMenuOptionBuilder<O>> typeToken = new
            TypeToken<AbstractMenuOptionBuilder<O>>(getClass()) { };

    public abstract O create();
}

这是class建造者的具体做法:

public class MenuOptionBuilder<O extends IClickable> extends AbstractMenuOptionBuilder<O> {

    public O create() {
        TypeToken<?> genericOptionParam = typeToken.resolveType(AbstractMenuOptionBuilder.class.getTypeParameters()[0]);

        Class<O> optionClass;

        try {

            optionClass = (Class<O>) Class.forName(genericOptionParam.getType().getTypeName());

             <.... snip ....>

        } catch(ClassNotFoundException e) {
            log.catching(e);
            return null;
        }
    }
}

我有一个菜单abstract基础class,它具有一种返回菜单选项列表的方法:

public abstract class AbstractMenu<O extends IClickable> {

    public final List<O> getOptions() {

        //This is where my plan doesn't work. The runtime type is given by
        //a concrete menu class which extends AbstractMenu, but that runtime
        //type doesn't seem to pass through to the abstract base class for the builder.
        MenuOptionBuilder<O> builder = new MenuOptionBuilder<O>(new MenuOptionBean()){};

             <.... snip ....>
    }

}

我有一个具体的菜单classextends它:

   //The runtime type of 'Link' is not known by the type token that is supposed to
   //resolve it in the abstract builder base class.
   public SimpleMenu extends AbstractMenu<Link> {
       <.... snip ....>
   }

我曾期望genericOptionParamin
中的变量MenuOptionBuilder可以解析为通用类型参数的名称,而不是其运行时类型为Link,但不能解析为。如果我像这样创建一个额外的基础,则通用参数可以正确解析:O``Link``class

public abstract class AbstractSimpleLinkedMenu extends AbstractMenu<Link> {

    public final List<Link> getOptions() {

        MenuOptionBuilder<Link> builder = new MenuOptionBuilder<Link>(new MenuOptionBean()){};
        <.... snip ....>
    }
}

我不希望不必添加其他基础类,例如AbstractSimpleLinkedMenu,那么这里是否有我错过或做错的事情?我以为抽象生成器的匿名内部类会知道运行时类型,如果使用通用参数声明该生成器,则不会。运行时类型由具体菜单class,指定SimpleMenu,但似乎无法过滤到abstract菜单选项的构建器类。


问题答案:

这就是TypeToken “ hack”的
工作方式。它使用Class#getGenericSuperclass()(或getGenericSuperInterface)。它的javadoc状态

如果超类是参数化类型,则Type返回的对象必须准确反映 源代码中使用的实际类型参数。

在这种情况下,也就是O,在这里

public abstract class AbstractMenuOptionBuilder<O extends IClickable>

您将获得源代码中的硬编码内容。如果您将代码硬编码Link为类型参数,请按照此处的操作

MenuOptionBuilder<Link> builder = 
    new MenuOptionBuilder<Link>(new MenuOptionBean()) {};

然后你会得到Link

在这种情况下

MenuOptionBuilder<O> builder = 
    new MenuOptionBuilder<O>(new MenuOptionBean()){};

您已经进行了硬编码O,这就是您将得到的。



 类似资料:
  • 我正在为Selenium测试框架开发一个构建泛型菜单的框架,我一直在使用Guava TypeToken来解析泛型参数的类型,但现在我遇到了一个问题,类型标记无法解析参数: 我有一个<code>抽象<code>基<code>类<code>用于生成菜单选项的生成器: 这是构建器的具体: 我有一个用于菜单的基,它有一个返回菜单选项列表的方法: 我有一个具体的菜单< code >类,它< code >扩展

  • 我有一个测试用例,在我的本地日食环境中运行良好。 但当我在Gitlab中使用同样的方法时,它失败了。我使用了下面的docker图片:maven:3.3.9-jdk-8。 它下载并提取chrome驱动程序https://chromedriver.storage.googleapis.com/90.0.4430.24/chromedriver_linux64.zip2021-05-17 16:33:5

  • @可在Service1和service2中注入 tsconfig.json emitDecoratorMetadata设置为true 在NGModule的提供者部分注册了Service1和Service2 如果有关系的话:我正在构建一个Ionic2RC0应用程序。以下是重要的文件: app.module.ts

  • 我正在尝试使用组件并显示一个对话框。只有当我需要使用时,才会出现此错误。只要不插入就可以创建对话框。 我见过类似这样的问题的其他答案,但我似乎无法将其转化为我的解决方案。需要做些什么才能让它不失败? MessageDialog.component.ts 错误:无法解析MdlDialogReference:(?)的所有参数。在SyntaxError.zoneawareerror(http://loc

  • 问题内容: 这是我第一次尝试使用ui-router。 这是我的app.js 如您所见,我有两种状态。我正在尝试这样注册状态: 但是我越来越 无法从状态“解析”“注册” 例外。这里有什么问题? 问题答案: 这种错误通常表示(JS)代码的某些部分未加载。里面的状态不见了。 有一个可行的例子 我不是离子技术方面的专家,因此此示例应表明它可以正常工作,但我使用了更多技巧(用于制表符的父级) 这是一个调整后

  • 这似乎意味着没有提供http和图标配置参数,但是图标配置是在应用程序模块级别提供的,并且导入到,其中提供了。 和图标组件的桶。