[英]Why does inferring of generic type does not work here?
Suppose I have the following classes: 假设我有以下类:
interface MyS<T extends MyT<S, T>, S extends MyS<T, S>> {
}
interface MyT<S extends MyS<T, S>, T extends MyT<S, T>> {
}
public class MySImpl implements MyS<MyTImpl, MySImpl> {
}
public class MyTImpl implements MyT<MySImpl, MyTImpl> {
}
I can build the following testcase which compiles and runs successfully without any warning: 我可以构建以下测试用例,它可以在没有任何警告的情况下成功编译和运行:
public class STTest {
@Test
public void test() throws Exception {
createInstance(MyTImpl.class);
}
public static<T extends MyT<S, T>, S extends MyS<T, S>> void createInstance(
final Class<? extends MyT<S, T>> beanClass) throws Exception {
final MyT<S, T> bean = beanClass.newInstance();
}
}
OK, fine. 好的。 But I expected that this would have the identical effect:
但我希望这会产生相同的效果:
public class STTest {
@Test
public void test() throws Exception {
createInstance(MyTImpl.class);
}
public static<T extends MyT<S, T>, S extends MyS<T, S>> void createInstance(
final Class<T> beanClass) throws Exception {
final T bean = beanClass.newInstance();
}
}
However, this is a compile error: 但是,这是一个编译错误:
invalid inferred types for S;
S的无效推断类型; inferred type does not conform to declared bound(s) inferred: MySImpl bound(s): MyS
推断类型不符合推断的声明边界:MySImpl bound(s):MyS
Why is this? 为什么是这样?
UPDATE: 更新:
I noticed that the behaviour is compiler dependent. 我注意到该行为依赖于编译器。 I used the OpenJDK 1.6 compiler (javac 1.6.0_27) for compiling to code.
我使用OpenJDK 1.6编译器(javac 1.6.0_27)来编译代码。 And it breaks.
它打破了。 However:
然而:
both work fine on the second example. 在第二个例子中都可以正常工作。
However: Is this a bug in the OpenJDK 1.6 compiler or is this an ambiguity in the Java language specification? 但是:这是OpenJDK 1.6编译器中的错误还是Java语言规范中的歧义?
The argument type doesn't mention S in any way in the second example. 参数类型在第二个示例中没有以任何方式提及S. The compiler is telling you that it therefore can't infer it.
编译器告诉你它因此无法推断它。
To elaborate. 详细说明。 In the first example, you ask for a
Class<? extends MyT<S, T>>
在第一个例子中,你要求一个
Class<? extends MyT<S, T>>
Class<? extends MyT<S, T>>
. Class<? extends MyT<S, T>>
。 In test()
, you give it a Class<MyTImpl>
. 在
test()
,你给它一个Class<MyTImpl>
。 As the compiler checks the bounds, it matches MyT<S, T>
against MyTImpl
and finds that MyTImpl
implements MyT<MySImpl, MyTImpl>
, so it can infer MySImpl
for S
and MyTImpl
for T
by simply placing those two things alongside. 当编译器检查边界时,它将
MyT<S, T>
与MyTImpl
匹配MyT<S, T>
并发现MyTImpl
实现MyT<MySImpl, MyTImpl>
,因此它可以通过简单地将这两个东西放在一起来推断出MySImpl
的S
和MyTImpl
for T
Then it checks the constraints on S
and T
for MySImpl
and MyTImpl
, which succeeds. 然后它检查
S
和T
对MySImpl
和MyTImpl
,然后成功。
In the second example, you ask for a Class<T>
. 在第二个示例中,您要求
Class<T>
。 The compiler sees Class<MyTImpl>
, infers MyTImpl
for T
, and is done. 编译器看到
Class<MyTImpl>
,推断MyTImpl
T
MyTImpl
,并且完成了。 Failing to infer S
, it errors out. 如果没有推断出
S
,就会出错。
Constraint checking for T
, which could provide the information what S
is, doesn't happen. 对
T
约束检查可以提供S
的信息,但不会发生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.