【发布时间】:2012-02-19 12:37:46
【问题描述】:
我有一个类层次结构,其中表兄弟共享非常相似的功能。例如:
Node
Statement
FunctionCallStatement
Expression
FunctionCallExpression
FunctionCallStatement 和 FunctionCallExpression 共享一个非常相似的 API,但我无法用单一继承层次结构的纯类术语来表达它。所以,我创建了一个 IsFunctionCall 接口,这两个接口都实现了。我现在可以声明一个采用 FunctionCallStatement 或 FunctionCallExpression 的方法,如下所示:
void <T extends Node & IsFunctionCall> doSomething(T node) { ... }
这一切都很好。
不幸的是,我现在发现自己面临一个相当尴尬的问题。我有一个节点;我动态地知道它必须是 FunctionCallStatement 或 FunctionCallExpression;我需要将该节点传递给上面的doSomething() 方法。我找不到将其向上转换为适当类型的方法。
现在我正在使用 instanceof 链来确定 Node 是哪个类并将其转换为适当的具体类型,但这很丑陋。我知道使这项工作的唯一其他方法是创建一个 IsNode 接口,并让当前期望 Node 的所有内容都期望 IsNode ;这将允许我声明一个实现 IsNode 和 IsFunctionCall 的联合接口,并让我在没有上述泛型的情况下取消。但这需要大量的工作,而且仍然很丑。
有没有其他方法可以做到这一点?
(注意:上面的例子是我实际代码的简化版本。)
更新:我尝试了以下邪恶:
@SuppressWarnings("unchecked")
private <S extends Node & IsFunctionCall> S castNode(Node node)
{
return (S) node;
}
然后:
doSomething(castNode(node));
我收到了一些 非常 奇怪的错误消息。用于确定castNode() 的 S 的类型推断似乎与doSomething() 的声明中的 T 不匹配;它仅使用具体类型并将 S 设置为节点。这当然与doSomething() 的声明类型不匹配。很奇特。
更新更新:
这似乎是How should I cast for Java generic with multiple bounds? 的近似副本。我的情况略有不同,因为我的边界包括一个对象和一个接口,而另一个问题中的边界有两个接口,但它仍然适用。
看来我需要重新设计我的整个应用程序。叹息。
任何管理员,请随意将其作为重复项关闭...
【问题讨论】: