我正在开发一个小程序,我正在尝试使用Java 8学习更多功能的编程风格。
这是有问题的代码
private Function<String, IOMessage<List<Polygon>>> parseSuccessfulShapesInput = (input) -> {
try {
List<Polygon> shapes =
Arrays.stream(input.split(";"))
.map(shape -> Arrays.stream(shape.split(","))
.map(pointString -> Arrays.asList(pointString.trim().split(" ")))
.map(coordList -> {
if (coordList.size() != 2) {
throw new RuntimeException("Points given must contain exactly two coordinates");
} else {
return new Point(Double.valueOf(coordList.get(0)), Double.valueOf(coordList.get(1)));
}
}).collect(Collectors.toList()))
.map(Polygon::new)
.collect(Collectors.toList());
return new IOMessage.Success<>(shapes);
} catch (Exception e) {
Exception fail = new Exception("Failed to parse shapes input.", e);
return new IOMessage.Error<>(fail);
}
};
private Function<IOMessage<String>, IOMessage<List<Polygon>>> parseShapesInput = (input) ->
input.match((IOMessage.Success<String> s) -> parseSuccessfulShapesInput.apply(s.payload),
(IOMessage.Error e) -> new IOMessage.Error<>(e.t),
(IOMessage.Quit q) -> new IOMessage.Quit<>()
);
我的IDE(Intellij)没有显示任何错误,但是当我编译它时,我收到以下错误:
Error:(107, 20) java: incompatible types: bad return type in lambda expression
inferred type does not conform to upper bound(s)
inferred: PolyPath.IOMessage<? extends java.lang.Object>
upper bound(s): PolyPath.IOMessage<java.util.List<PolyPath.Polygon>>,java.lang.Object
如果我尝试将显式类型添加到parseShapesInput
,请执行以下操作:
private Function<IOMessage<String>, IOMessage<List<Polygon>>> parseShapesInput = (input) -> {
return input.match((IOMessage.Success<String> s) -> parseSuccessfulShapesInput.apply(s.payload),
(IOMessage.Error e) -> new IOMessage.Error<IOMessage<List<Polygon>>>(e.t),
(IOMessage.Quit q) -> new IOMessage.Quit<IOMessage<List<Polygon>>>()
);
};
Intellij给了我以下错误:
Incompatible types: IOMessage<capture of ? extends Object> is not convertible to IOMessage<List<Polygon>>
我的IOMessage代码:
public abstract class IOMessage<T> {
private IOMessage() {
}
public abstract <M> M match(Function<Success<T>, M> s,
Function<Error, M> e,
Function<Quit, M> q);
public static final class Success<S> extends IOMessage<S> {
public final S payload;
public <M> M match(Function<Success<S>, M> s,
Function<Error, M> e,
Function<Quit, M> q) {
return s.apply(this);
}
public Success(S payload) {
this.payload = payload;
}
}
public static final class Error<S> extends IOMessage<S> {
public final Throwable t;
public <M> M match(Function<Success<S>, M> s,
Function<Error, M> e,
Function<Quit, M> q) {
return e.apply(this);
}
public Error(Throwable t) {
this.t = t;
}
}
public static final class Quit<S> extends IOMessage<S> {
public <M> M match(Function<Success<S>, M> s,
Function<Error, M> e,
Function<Quit, M> q) {
return q.apply(this);
}
public Quit() {
}
}
}
答案 0 :(得分:1)
我无法解释为什么编译器不喜欢你的代码,但你可以将方法更改为
private Function<IOMessage<String>, IOMessage<List<Polygon>>> parseShapesInput = (
input) -> {
if (input instanceof IOMessage.Success) {
return parseSuccessfulShapesInput
.apply(((IOMessage.Success<String>) input).payload);
}
if (input instanceof IOMessage.Error) {
return new IOMessage.Error<>(((IOMessage.Error<String>) input).t);
}
return new IOMessage.Quit<>();
};
我尝试了不同的东西,如果你删除了Error
和Quit
的实例化,并通过parseSuccessfulShapesInput#apply
的调用替换它,编译器就会很高兴。我认为最好的解释是编译器有时会混淆(在其他场合也会发生)。
import java.util.function.Function;
public abstract class IOMessage<T> {
private IOMessage() {
}
public abstract <M> M match(Function<Success<T>, M> s,
Function<Error<T>, M> e, Function<Quit<T>, M> q);
public static final class Success<S> extends IOMessage<S> {
public final S payload;
public <M> M match(Function<Success<S>, M> s, Function<Error<S>, M> e,
Function<Quit<S>, M> q) {
return s.apply(this);
}
public Success(S payload) {
this.payload = payload;
}
}
public static final class Error<S> extends IOMessage<S> {
public final Throwable t;
public <M> M match(Function<Success<S>, M> s, Function<Error<S>, M> e,
Function<Quit<S>, M> q) {
return e.apply(this);
}
public Error(Throwable t) {
this.t = t;
}
}
public static final class Quit<S> extends IOMessage<S> {
public <M> M match(Function<Success<S>, M> s, Function<Error<S>, M> e,
Function<Quit<S>, M> q) {
return q.apply(this);
}
public Quit() {
}
}
}