Java Wicket (6.19) IVisitor 参数传递
Java Wicket (6.19) IVisitor argument passing
问题
我一直在查看 wicket-util-6.19 源代码、样本库等教程,但没有找到这个问题的答案。
这个问题是关于我可以与 IVisitor.
一起使用什么样的参数(专业化)
剧透:我知道如何让代码工作,我只是想知道为什么我不能按照我想要的方式去做。
我有一个 NestedTree。如果您熟悉 wicket-6 NestedTree,您可能知道该树由 Node 组成,其模型是您声明树的对象。所以它由 Node 组成(树比那个更复杂——这只是为了举例)。
来访
我想用一个访问者遍历树,return MyObjectType 对象支持 Node 基于 PropertyEn(一个枚举,但可以是数字或任何东西)。
我会这样写这次访问:
private MyObjectType findNode(final PropertyEn propertyEn) {
return myNestedTree.visitChildren(new IVisitor<Node<MyObjectType>, MyObjectType>() {
@Override
public void component(Node<MyObjectType> object, IVisit<MyObjectType> visit) {
if ( object.getModelObject().getPropertyEn == propertyEn ) {
visit.stop(object.getModelObject());
}
}
});
第一个 IVisitor 泛型参数 Node object
的使用存在泛型问题
...Cannot instantiate from arguments because actual and formal arguments lists differ in length...
让它发挥作用
这可以编译并可能工作,但需要未经检查的转换和反射:
private MyObjectType findNode(final PropertyEn propertyEn) {
return myNestedTree.visitChildren(new IVisitor<Node<MyObjectType>, MyObjectType>() {
@Override
public void component(Component object, IVisit<MyObjectType> visit) {
if ( object instanceof Node) {
if (((Node<PropertyEn>) object).getModelObject().getProto() == lxproto) {
visit.stop(((Node<PropertyEn>) object).getModelObject());
}
// A Node has no concept of nesting. The tree is made as such with other data structures.
// No need to go deeper within an Node thus.
visit.dontGoDeeper();
}
}
)};
问题
为什么我不能只使用专门的类型作为 IVisitor 的第一个类型参数?
我发现了问题...这是 visitChildren() 方法的签名。
我用的是:
public final <R> R visitChildren(final IVisitor<Component, R> visitor)
{ ... }
我应该使用的是:
public final <S extends Component, R> R visitChildren(final Class<?> clazz, final IVisitor<S, R> visitor)
{ ... }
所以代码看起来像这样:
private MyObjectType findNode(final PropertyEn propertyEn) {
return myNestedTree.visitChildren(Node.class, new IVisitor<Node<MyObjectType>, MyObjectType>() {
@Override
public void component(Node<MyObjectType> object, IVisit<MyObjectType> visit) {
if ( object.getModelObject().getPropertyEn() == propertyEn ) {
visit.stop(object.getModelObject());
}
}
)};
问题
我一直在查看 wicket-util-6.19 源代码、样本库等教程,但没有找到这个问题的答案。 这个问题是关于我可以与 IVisitor.
一起使用什么样的参数(专业化)剧透:我知道如何让代码工作,我只是想知道为什么我不能按照我想要的方式去做。
我有一个 NestedTree。如果您熟悉 wicket-6 NestedTree,您可能知道该树由 Node 组成,其模型是您声明树的对象。所以它由 Node
来访
我想用一个访问者遍历树,return MyObjectType 对象支持 Node 基于 PropertyEn(一个枚举,但可以是数字或任何东西)。
我会这样写这次访问:
private MyObjectType findNode(final PropertyEn propertyEn) {
return myNestedTree.visitChildren(new IVisitor<Node<MyObjectType>, MyObjectType>() {
@Override
public void component(Node<MyObjectType> object, IVisit<MyObjectType> visit) {
if ( object.getModelObject().getPropertyEn == propertyEn ) {
visit.stop(object.getModelObject());
}
}
});
第一个 IVisitor 泛型参数 Node
...Cannot instantiate from arguments because actual and formal arguments lists differ in length...
让它发挥作用
这可以编译并可能工作,但需要未经检查的转换和反射:
private MyObjectType findNode(final PropertyEn propertyEn) {
return myNestedTree.visitChildren(new IVisitor<Node<MyObjectType>, MyObjectType>() {
@Override
public void component(Component object, IVisit<MyObjectType> visit) {
if ( object instanceof Node) {
if (((Node<PropertyEn>) object).getModelObject().getProto() == lxproto) {
visit.stop(((Node<PropertyEn>) object).getModelObject());
}
// A Node has no concept of nesting. The tree is made as such with other data structures.
// No need to go deeper within an Node thus.
visit.dontGoDeeper();
}
}
)};
问题
为什么我不能只使用专门的类型作为 IVisitor 的第一个类型参数?
我发现了问题...这是 visitChildren() 方法的签名。
我用的是:
public final <R> R visitChildren(final IVisitor<Component, R> visitor)
{ ... }
我应该使用的是:
public final <S extends Component, R> R visitChildren(final Class<?> clazz, final IVisitor<S, R> visitor)
{ ... }
所以代码看起来像这样:
private MyObjectType findNode(final PropertyEn propertyEn) {
return myNestedTree.visitChildren(Node.class, new IVisitor<Node<MyObjectType>, MyObjectType>() {
@Override
public void component(Node<MyObjectType> object, IVisit<MyObjectType> visit) {
if ( object.getModelObject().getPropertyEn() == propertyEn ) {
visit.stop(object.getModelObject());
}
}
)};