Следующий код аварийно завершает работу во время выполнения, но если вы измените эту строку так, чтобы 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