【问题标题】:Casting to a bounded type强制转换为有界类型
【发布时间】: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? 的近似副本。我的情况略有不同,因为我的边界包括一个对象和一个接口,而另一个问题中的边界有两个接口,但它仍然适用。

看来我需要重新设计我的整个应用程序。叹息。

任何管理员,请随意将其作为重复项关闭...

【问题讨论】:

标签: java generics


【解决方案1】:

我认为解决这个问题的方法,虽然不是很优雅,但是为 doSomething 设置一些重载:

void doSomething(FunctionCallStatement node) ...
void doSomething(FunctionCallExpression node) ...

【讨论】:

    【解决方案2】:

    您正在使用接口来标记功能,如何将引用作为参数传递给FunctionCallInterface,它提供对函数调用抽象的访问?

    doSomething 不必知道实际的实现类型,只要它可以访问相关信息并调用实现对象上的相关方法即可。

    public class FunctionCallStatement extends Statement implements FunctionCallInterface {
    }
    
    void doSomething(FunctionCallInterface node) {
    }
    

    【讨论】:

    • doSomething() 需要访问 Node 功能以及 FunctionCallInterface 功能,因此是泛型类型的原因。我想我可以传入一个节点 一个 FunctionCallInterface,尽管它们最终都会成为同一个对象......
    • @David Given,您可以定义 Node 实现的 NodeInterface,并让 FunctionCallInterface 扩展它,以便它提供您需要的所有功能。
    猜你喜欢
    • 2010-11-11
    • 2014-02-04
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多