java - 将一种方法标记为首选以自动解决不明确的调用?

标签 java ambiguous-call

假设我自己定义了一种新型字节流(类似于 OutputStream):

public interface MyByteStream {
    public void write(byte[] data) throws IOException;
}

另外,我有一个可以将字符串写入字节流的辅助类,为了灵 active ,我希望它的方法有两个版本,以便它可以与常规 OutputStream 或我的新 MyByteStream 一起使用:

public class StringWriter {
    public void write(String string, MyByteStream stream) throws IOException {
        stream.write(string.getBytes());
    }

    public void write(String string, OutputStream stream) throws IOException {
        stream.write(string.getBytes());
    }
}

现在,如果我有一个类扩展 OutputStream 实现 MyByteStream,像这样:

public class DebugStream extends OutputStream implements MyByteStream {
    @Override
    public void write(int b) throws IOException {
        System.out.println(b);
    }
}

我不能像这样调用我的 StringWriter 的写入方法:

new StringWriter().write("Hello", new DebugStream());

因为它会给我以下错误:

The method write(String, MyByteStream) is ambiguous for the type StringWriter

我可以通过将 DebugStream 显式转换为字节流之一来解决问题,如下所示:

new StringWriter().write("Hello", (OutputStream) new DebugStream());
new StringWriter().write("Hello", (MyByteStream) new DebugStream());

但是由于这两种方法无论如何都做完全相同的事情,所以我宁愿不必在所有地方都进行转换。有什么办法解决这个问题吗?就像将其中一种方法定义为此类模棱两可的调用的首选方法一样?或者也许是一些泛型诡计?

注意:

我想保持编译时类型安全性,因此以下几行的“解决方案”已经过时:

public class StringWriter {
    public void write(String string, Object stream) throws IOException {
        if (stream instanceof OutputStream) {
            ((OutputStream) stream).write(string.getBytes());
        } else if (stream instanceof MyByteStream) {
            ((MyByteStream) stream).write(string.getBytes());
        } else {
            throw new IllegalArgumentException();
        }
    }
}

最佳答案

主要有两个选项:

1) 以不同的方式命名方法,而不是重载现有方法:

public void write(String string, OutputStream stream) {
    //
}

public void writeMyByteStream(String string, MyByteStream stream) {
    //
}

这不是一个好的解决方案,因为它会用实现细节污染 API,但这是一个选项。

2) 使用一种公共(public)方法,但私下选择如何处理流类型:

public void write(String string, OutputStream stream) {
    if (stream instanceof MyByteStream) {
        writeMyByteStream(string, stream);
    } else {
        writeOutputStream(string, stream);
    }
}

private void writeMyByteStream(String string, MyByteStream stream) {
    //
}

private void writeOutputStream(String string, OutputStream stream) {
    //
}

第二种方法更简洁,因为 API 简单得多,客户不需要知道该类使用 MyByteStream 做了任何特殊的事情。这也意味着以后可以在不更改任何客户端代码的情况下从实现中撤消特殊支持。

有些人可能会从样式角度质疑使用 instanceof,但是当您需要它时,您就需要它。

关于java - 将一种方法标记为首选以自动解决不明确的调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24481796/

相关文章:

Java:子线程可以比主线程长寿吗

java - 如何根据用户输入更改 Android 应用程序的背景颜色?

java - 为什么索引大于for循环条件会导致异常[Java]?

haskell - 在 Haskell 中使用 Read 和 Show 时(缺乏)二义性类型

haskell - 使用 DuplicateRecordFields 消除记录更新的歧义

java - JPA:所有实体一个 DAO 还是每个实体一个?

java - 有条件等待

java - 向 Mockito.any() 提供类以使 verify() 调用明确的正确语法是什么?

haskell - 与 TypeApplications 一起使用时,AllowAmbigouslyTypes 有多危险?

c++ - 对 'distance'的错误引用是含糊的