런타임에 다음 코드가 충돌하지만 Model & Serializable
이 Serializable & Model
이되도록 한 행을 변경하면 정상적으로 실행됩니다. 아무도 무슨 일이 일어나고 있는지 설명 할 수 있습니까? 이것은 Java의 버그입니까? 유형 범위의 순서가 중요해야하는 것처럼 보이지 않습니다.두 유형 매개 변수 범위의 순서를 변경하면 Java 런타임 오류가 발생합니다.
import java.io.Serializable;
interface Model {
void foo();
}
class ModelA implements Model, Serializable {
public void foo() {
}
}
class MemcachedHelper<T extends Serializable> {
T getCached(String key, Maker<T> make) {
return make.get();
}
interface Maker<U extends Serializable> {
U get();
}
}
class Query {
Object getResult() {
return new ModelA();
}
}
public class Main {
// private static <T extends Serializable & Model>
private static <T extends Model & Serializable>
T getModel(Class<T> modelClass, MemcachedHelper<T> cache) {
String key = "key:" + modelClass.getSimpleName();
T thing = cache.getCached(key,() -> {
Query q = new Query();
return (T)q.getResult();
});
return thing;
}
public static void main(String[] args) {
MemcachedHelper<ModelA> cache = new MemcachedHelper<>();
Model thing = getModel(ModelA.class, cache);
System.out.printf("Got thing: %s\n", thing);
}
}
런타임 오류는 다음과 같습니다
Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
at java.lang.invoke.CallSite.makeSite(CallSite.java:341)
at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
at Main.getModel(Main.java:33)
at Main.main(Main.java:42)
...
Caused by: java.lang.invoke.LambdaConversionException: Type mismatch for lambda expected return: interface Model is not convertible to interface java.io.Serializable
at java.lang.invoke.AbstractValidatingLambdaMetafactory.validateMetafactoryArgs(AbstractValidatingLambdaMetafactory.java:286)
at java.lang.invoke.LambdaMetafactory.metafactory(LambdaMetafactory.java:303)
at java.lang.invoke.CallSite.makeSite(CallSite.java:302)
... 9 more
이 JDK 버전 1.8.0_101입니다.
나는 생각한다, 그것은 [이 질문] (http://stackoverflow.com/q/27031244/2711488)의 중복이다. 문제의 유형은 수신자 유형보다는 리턴 유형이지만, 교차 유형의 잘못된 처리가 동일합니다. – Holger