【问题标题】:Avoiding ambiguous methods caused by extends/implements避免由扩展/实现引起的模棱两可的方法
【发布时间】:2014-01-26 15:18:31
【问题描述】:

我有一个方便的函数,它接受各种类型的对象并以可序列化的方式将它们转换。例如,将类 JSON 对象转换为 JSON:

public static <T> String process( List<T> list ) {
    if( list instanceof JSONArray ) {
        return ((JSONArray) list).toJSONString( );
    }
    // stringify the list
}
public static String process( JSONAware object ) { // array, map, value, ...
    return object.toJSONString( );
}

我正在使用org.json.simple 库,所以JSONArray extends ArrayList implements JSONAware。但这意味着当我发送 JSONArray 时,我得到:

对进程的引用不明确

我知道它同样适用于任何一种方法,这就是为什么我在这两种方法中都有相同的实现。

很明显,我可以将这两个函数替换为一个采用任意 Object 类型的函数,但这会消除很多我不满意的编译时检查。我还可以重命名其中一个函数以强制进行特定选择,但这会使 API 复杂化。

有没有什么方法可以强制一个特定的选择,或者让编译器明白在这些情况下调用哪个方法并不重要?

【问题讨论】:

  • 你有第二个吗 - 你可以在对象上调用 toJSONString
  • 这是代码的简化示例。把它想象成serialize-over-http;它还存储有关已发送对象类型的信息。我正在使用它,以便基于 Web 的界面可以显示有关任意对象的信息(并且对象的类型包含在发送的数据中)

标签: java generics operator-overloading


【解决方案1】:

你可以添加

public static void process(JSONArray array) {
    process((JSONAware) array);
}

虽然这不是一个通用的解决方案,但它会在这种情况下解决它。


在这个例子中

public class Example {

    static class A {

    }

    interface B {

    }

    static class C extends A implements B {

    }

    static void process(A a) {

    }

    static void process(B b ) {

    }

    static void process(C c) {
        System.out.println("process C called");
    }

    public static void main(String... ignored) {
        process(new C());
    }

打印

process C called

【讨论】:

  • 我已经尝试过了,但是没有用;错误只是移动到 JSONArray 和 List 版本之间,而不是 JSONAware/List 版本。
  • @Dave 我会检查您拥有的 Java 版本。我尝试了 Java 7 更新 51。
  • 啊,我被一些在 6 上运行的遗留代码卡住了。这可能是一个固定功能吗?
  • 我的系统上不再有 Java 6。我建议你尝试最新版本的 Java 6 看看。
  • 嗯,您发布的代码可以正常工作,除非 A 是通用的;将&lt;T&gt; 添加到process(A) 函数和A 类会使其失败,除非C 在扩展A 时也定义了一个类型。所以这个错误似乎是因为 org.json.simple 扩展了一个原始的List 而不是List&lt;Object&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
  • 2016-02-19
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多