我有两个多态方法,采用两种类型的类作为输入。
我希望基于对象的流执行两个不同的操作。
相反,他告诉我这个方法有歧义。
不使用流显然可以工作。我的目的是使用它们。
怎么解?
帮帮我,我不明白。谢谢。Stream.of(1,"Text").forEach(Test::method);
static void method(Integer i){
System.out.println("i");
}
static void method(String i){
System.out.println("s");
}
如果你将流赋值给一个局部变量,你会看到Stream.of(1,"Text")
的类型是Stream<Object>
Stream<Object> x = Stream.of(1,"Text");
因此forEach所需的方法类型是:
static void method(Object obj){
System.out.println("Object is: "+obj);
}
如果您使用了Stream.of(1,2)
或Stream.of("Hello", "Text")
,那么方法调用将按照您的预期进行解析。
您可以添加一个接受Object参数的方法,并使用这种方法:
import java.util.stream.Stream;
public class Test {
static void method(Object o) {
if(o instanceof String)
method((String)o);
if(o instanceof Integer)
method((Integer)o);
}
static void method(Integer i) {
System.out.println("i");
}
static void method(String i) {
System.out.println("s");
}
public static void main(String[] args) {
Stream.of(1, "Text").forEach(element -> {
Test.method( element );
});
}
}
Java只在编译时解析重载。当迭代1
时,您似乎希望Test::method
解析为method(Integer)
(第一次重载),并在迭代"Text"
时解析为method(String)
(第二次重载)。这是不可能的,Test::method
只能解析一件事。
错误信息确实有点令人困惑。问题不在于这两种方法之间存在歧义。问题是,由于流中既有字符串又有整数,forEach
希望您为它提供一个方法,该方法可以接受字符串和整数(或者更准确地说,是String
和Integer
之间的通用超类型,因为Java中没有联合类型)。
static void method(Object o){
}
但是method
的两个重载都不能同时接受字符串和整数。
要做你想做的,你必须在运行时检查类型,并手动调用重载:
Stream.of(1,"Text").forEach(x -> {
if (x instanceof Integer) {
method((Integer)x);
} else if (x instanceof String) {
method((String)x);
}
});
我建议你不要将字符串和整数放在同一个流中。
如果涉及的类型不是String
和Integer
,而是您编写的类,情况将不同。因为这样您就可以将method
编写为公共超类中的实例方法。与重载解析不同,选择运行的实例方法的覆盖实现是在运行时完成的。
class Superclass {
public void method() {
}
}
class BaseClass1 extends Superclass {
@Override
public void method() {
System.out.println("i");
}
}
class BaseClass2 extends Superclass {
@Override
public void method() {
System.out.println("s");
}
}
// ...
Stream.of(new BaseClass1(), new BaseClass2()).forEach(Superclass::method);
由于Stream.of(1, "Text", null)
中的元素类型是所有三个参数的共同超类型,因此可以实现接受Object
类型参数的方法,以将调用分派到适当的重载method
(null
值也应处理为映射到某些特定的方法):
Stream.of(1,"Text", null).forEach(Test::method);
static void method(Object o) {
if (o instanceof Integer) {
method((Integer) o);
} else if (o instanceof String || null == o) {
method((String) o);
} else {
method(o.toString());
}
}
输出:
i
s
s
关于语句:
不使用流显然可以工作。
这似乎不是真的。
如果一个原始列表/数组被创建并使用,而不是流,也会出现类似的问题:
List list = Arrays.asList(1, "Text", null);
// list.forEach(Test::method); // fails too, same error as below
for (int i = 0; i < list.size(); i++) {
method(list.get(i));
}
在这种情况下,错误看起来像:
/Test.java:10: error: no suitable method found for method(Object)
method(list.get(i));
^
method Test.method(Integer) is not applicable
(argument mismatch; Object cannot be converted to Integer)
method Test.method(String) is not applicable
(argument mismatch; Object cannot be converted to String)
1 error