Java 无法从Guava解析泛型参数TypeToken
我正在为Selenium测试框架开发一个构建泛型菜单的框架,我一直在使用Guava TypeToken来解析泛型参数的类型,但现在我遇到了一个问题,类型标记无法解析参数: 我有一个Java 无法从Guava解析泛型参数TypeToken,java,generics,guava,Java,Generics,Guava,我正在为Selenium测试框架开发一个构建泛型菜单的框架,我一直在使用Guava TypeToken来解析泛型参数的类型,但现在我遇到了一个问题,类型标记无法解析参数: 我有一个摘要base类,用于生成菜单选项的生成器: public abstract class AbstractMenuOptionBuilder<O extends IClickable> { protected final TypeToken<AbstractMenuOptionBuilder
摘要
base类
,用于生成菜单选项的生成器:
public abstract class AbstractMenuOptionBuilder<O extends IClickable> {
protected final TypeToken<AbstractMenuOptionBuilder<O>> typeToken = new
TypeToken<AbstractMenuOptionBuilder<O>>(getClass()) { };
public abstract O create();
}
我有一个菜单的abstract
baseclass
,它有一个返回菜单选项列表的方法:
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 ....>
}
}
我希望MenuOptionBuilder
中的变量genericOptionParam
将解析为Link
,但它没有,而是解析为O
,泛型类型参数的名称,而不是它的运行时类型Link
。如果我像这样创建一个附加的base类
,则泛型参数将正确解析:
public abstract class AbstractSimpleLinkedMenu extends AbstractMenu<Link> {
public final List<Link> getOptions() {
MenuOptionBuilder<Link> builder = new MenuOptionBuilder<Link>(new MenuOptionBean()){};
<.... snip ....>
}
}
公共抽象类AbstractSimpleLinedMenu扩展了AbstractMenu{
公共最终列表getOptions(){
MenuOptionBuilder=new MenuOptionBuilder(new MenuOptionBean()){};
}
}
我不想添加额外的基类,比如
AbstractSimpleLinekedMenu
,那么这里是否有我遗漏或做得不正确的地方?我认为抽象构建器的匿名内部类应该知道运行时类型,但如果使用泛型参数声明构建器,则不会知道。运行时类型由具体菜单class
,SimpleMenu
指定,但它似乎没有过滤到菜单选项的abstract
builder类。这就是TypeToken
“hack”的工作方式。它使用(或getGenericSuperInterface
)。它的javadoc声明
如果超类是参数化类型,则返回type
对象
必须准确反映源中使用的实际类型参数
代码。
在这种情况下,即O
,此处
public abstract class AbstractMenuOptionBuilder<O extends IClickable>
然后您将获得链接
在这种情况下
MenuOptionBuilder<O> builder =
new MenuOptionBuilder<O>(new MenuOptionBean()){};
MenuOptionBuilder=
新建MenuOptionBuilder(新建MenuOptionBean()){};
您已经硬编码了O
,因此这就是您将得到的结果
以下是我在类型标记主题上写的更多内容:
- 这就是
TypeToken
“hack”的工作原理。它使用(或getGenericSuperInterface
)。它的javadoc声明
如果超类是参数化类型,则返回type
对象
必须准确反映源中使用的实际类型参数
代码。
在这种情况下,即O
,此处
public abstract class AbstractMenuOptionBuilder<O extends IClickable>
然后您将获得链接
在这种情况下
MenuOptionBuilder<O> builder =
new MenuOptionBuilder<O>(new MenuOptionBean()){};
MenuOptionBuilder=
新建MenuOptionBuilder(新建MenuOptionBean()){};
您已经硬编码了O
,因此这就是您将得到的结果
以下是我在类型标记主题上写的更多内容:
MenuOptionBuilder=new MenuOptionBuilder(new MenuOptionBean()){}代码>。当我用具体类型(如Link
)声明构建器时,其底层abstract
baseclass
中的类型标记可以将运行时类型解析为Link
。但是,我不能使用像O
这样的泛型类型参数来声明它,也不能依赖类型标记来解析conrete菜单class
extensingAbstractMenu
@Selena指定的运行时类型。我之前无法处理您的评论。但后来我又重读了所有的东西,完全如我所说。在MenuOptionBuilder
中,源代码使用具体类型Link
作为参数,因此getGenericSuperclass
将返回该类型。在MenuOptionBuilder
中,源代码包含类型参数O
作为类型参数。所以,同样,这就是将要返回的内容。@Selena但我将编辑我所说的内容以澄清,因为我看到我的最后一句话不是我的意思。我怀疑是这样的。我一直希望TypeToken能够从具体的菜单声明中派生出运行时类型,但这显然不会发生。不管怎样,我找到了一种绕过这个限制的方法。事实上,这条线是有效的。这是一个没有:MenuOptionBuilder=new MenuOptionBuilder(new MenuOptionBean()){}代码>。当我用具体类型(如Link
)声明构建器时,其底层abstract
baseclass
中的类型标记可以将运行时类型解析为Link
。但是,我不能使用像O
这样的泛型类型参数来声明它,也不能依赖类型标记来解析conrete菜单class
extensingAbstractMenu
@Selena指定的运行时类型。我之前无法处理您的评论。但后来我又重读了所有的东西,完全如我所说。在MenuOptionBuilder
中,源代码使用具体类型Link
作为参数,因此getGenericSuperclass
将返回该类型。在MenuOptionBuilder
中,源代码包含类型参数O
作为类型参数。所以,同样,这就是将要返回的内容。@Selena但我将编辑我所说的内容以澄清,因为我看到我的最后一句话不是我的意思。我怀疑是这样的。我一直希望TypeToken能够从具体的菜单声明中派生出运行时类型,但这显然不会发生。无论如何,我找到了一种绕过这个限制的方法。
MenuOptionBuilder<O> builder =
new MenuOptionBuilder<O>(new MenuOptionBean()){};