Can we represent “self class” in Java (or Kotlin)?

I think the question title is a little bit confusing, but I can't find a mo…
关注者
44
被浏览
5,275
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

看到回答很多在说泛型,没记错的话JAVA的泛型是会被“擦除”的,使用泛型并没有真的解决这个问题,只是把原本返回A变成返回Object,然后强制转换成BC。

具体来说,比如,List<A<? extends A>> as = Lists.of(B.bala(), C.bala()); ,差不多类似这样吧,从as中取出的元素A身上的泛型实际上还是丢失了B、C信息的,如果直接用 B b = a.bala() 来接收应该会失败吧?Captured不能运用到未Captured之类?宿舍断电了我也没法测,但觉得逻辑上是这样。

那么这个问题怎么解决呢?
1、不在意类型问题了,只要骗过编译器就好。那么只要这样:<T extends A> T bala(); 注意这里其实没有在接口A身上携带泛型信息,只是方法返回申明那里加了个泛型约束,效用与强制转换无异。如果你非要用B去接收本应该是C的A,还是会很惨。
2、一定要从一个简单抽象的接口得到具有更多信息的具体的类,那么当然需要反射。一个比较好的办法是通过自定义修饰器接口,在修饰器里持有self class信息,比如@WithSelfClass(values=B.class) 这样。

以上,我是这么想的,但毕竟纯理论没实验,不知道具体可不可行。


***

补充实验结果:

不能从A<?> 到B
不能从A<?>到A<B>
但可以从A<B>到A<C>

以上三张图,我相信足以说明问题,在这里用泛型,接口A仍然会丢失B、C的具体信息,无法通过编译器,类B、C却反过来丢失了自己的信息,导致A<B>到A<C>这样的转换反倒通过了编译器。


***

下面再来试试我的方案,第一种:

实现起来要简单多了,本来这里接口A身上携带泛型信息就没什么用,那还不如直接在bla()方法添加泛型约束,反正都是骗过编译器。

第二种:

诺,虽然麻烦了很多,但如果真的遇到这种需求,还是有所值的吧。