java 多个泛型,如何将Java泛型通配符与使用多个泛型参数的方法一起使用?

So we have a generic method like this, which is part of dependency injection initialisation:

public static void registerTransient(

Class serviceClass, Class implementationClass)

{

//

}

At some point we found a case where a class might not necessarily be present. And it's an implementation class which we would be injecting multiple off (so the service class is the same as the implementation class.) Naturally you would write this like this:

Class> clazz = Class.forName("com.acme.components.MyPersonalImplementation");

registerTransient(clazz, clazz);

IDEA has no problems with this, but javac complains:

error: method registerTransient in class TestTrash cannot be applied to given types;

required: Class,Class

found: Class,Class

reason: inferred type does not conform to declared bound(s)

inferred: CAP#2

bound(s): CAP#1

where TS,TI are type-variables:

TS extends Object declared in method registerTransient(Class,Class)

TI extends TS declared in method registerTransient(Class,Class)

where CAP#1,CAP#2 are fresh type-variables:

CAP#1 extends Object from capture of ?

CAP#2 extends Object from capture of ?

What gives? The method requires the second parameter to be a subclass of the first. Irrespective of what class ? happens to be, it's the same class object for both parameters and a class is, I thought, always assignable from itself. It's almost as if javac is unnecessarily inventing a second wildcard type to use for the second parameter and then going "oh dear, you have two wildcards here, so I can't tell if one is assignable from the other."

解决方案

The problem is that Class> cannot be cast to any other type unless via an explicit cast (it actually becomes Class during capture conversion). As such, the compiler cannot (statically) match the type bounds of those captures with the parameterized types of the method definition.

Try casting it explicitly to Class first, like in:

registerTransient((Class)clazz, clazz);

This way the compiler can bind TS to Object and TI to something that extends Object (it will still emit a warning, though).

The fact that IntelliJ's compiler does not complain about this, might be due to some optimization or might even be a compiler bug. You should post it as such and wait for a reply.

If you wish to check it with a slightly different approach, the following will still not compile, even though it "looks" ok:

public class A {

static class B {}

static class C extends B {}

static void method(final Class t, final Class r) {}

public static final void main(String... args) {

B b = new B();

C c = new C();

Class> cb = b.getClass();

Class> cc = c.getClass();

method(cb, cc);

}

}

Have a look in here. It presents an extraordinary view of Java's type system (although quite dense).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值