gpt4 book ai didi

具有访客模式反射的 Java 泛型

转载 作者:太空宇宙 更新时间:2023-11-04 07:28:49 24 4
gpt4 key购买 nike

我想确保在我的代码变得太大/太复杂而无法发布之前它可以工作。我没有足够的数据来测试这是否按我预期的方式工作

我正在做一些事情,我想在 AST 上使用访问者模式。我的目标是通过使用父类(super class)中的反射消除在每个子类中重写 accept(Visitor) 的需要,从而使访问者在实现新型 TreeNode 时几乎透明。

通过允许访问(TreeNode),它允许未知节点类型的默认方法,这样在添加新节点类型时不需要更改旧访问者。

类参数 R 和 P 是访问的返回值和参数,这是我在 programming stack exchange question 中学到的一个技巧。 .

为此,我有以下内容:

public abstract class TreeNode {
public final < R, P > R accept(TreeVisitor<R,P> v, P p){
try{
Method m = v.getClass().getMethod("visit", getClass(),Object.class);
return (R)m.invoke(v, this,p);
} catch (IllegalAccessException ex) {
} catch (IllegalArgumentException ex) {
} catch (InvocationTargetException ex) {
} catch (NoSuchMethodException nsme){
}
return (R)v.visit(this,p);
}
public abstract void contains(TreeNode n);//and other methods
}
//in another file
interface TreeVisitor<R,P> {
public R visit(TreeNode n,P p);//default
public R visit(TreeNodeSubclass tns,P p);
//all other subclasses as well
}
//from here lower is un-tested, written just now, just for this post, code
//somewhere else we have an algorithm to visit nodes
class DoStuff implements TreeVisitor<String,Void>{
public String visit(TreeNode n, Void v){
return n.toString();
}
public String visit(TreeNodeSubclass n, Void v){
return "SUB:" + n.toString();
}
}

//algorithm in a method somewhere
DoStuff ds = new DoStuff();
for(TreeNode node : inOrderTraverse(ROOT_NODE)){
node.accept(ds);
}

这会按我的预期工作吗(假设 inOrderTraverse(ROOT_NODE) 正确生成所有节点的列表)?

我的主要问题实际上是 getMethod 调用的部分,因为类型删除 Object.class 应该是正确的参数,即使由于通用参数 P 而更喜欢使用 p.getClass() 。但这是行不通的,因为类型删除会导致 Visitor 中的实际方法签名为 Object access(this.getClass(), Object)this.getClass() 指的是我正在使用 Node 子类的实际类来获取 Visitor 中正确的重载方法。

我对此的理解正确还是我遗漏了什么?

最佳答案

我不确定如果您传入 Object.class 作为参数类型是否会起作用,但我确实看到了另一个潜在问题:如果您的新节点具有私有(private)而不是公共(public)“访问”方法,那么您应该在异常中考虑它,例如:



<前>尝试{
方法 m = v.getClass().getMethod("访问", getClass(),Object.class);
return (R)m.invoke(v, this,p);
} catch (NoSuchMethodException e) {
尝试 {
方法 m = v.getClass().getDeclaredMethod("访问", getClass(),Object.class);
return (R)m.invoke(v, this,p);
} catch (异常 e){
return (R)v.visit(this,p);//默认
}
} catch (异常 e){
return (R)v.visit(this,p);//默认
}

关于具有访客模式反射的 Java 泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18093486/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com