- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我想确保在我的代码变得太大/太复杂而无法发布之前它可以工作。我没有足够的数据来测试这是否按我预期的方式工作
我正在做一些事情,我想在 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/
我是一名优秀的程序员,十分优秀!