我在理解Java泛型方面遇到了问题,我已经简化为这个例子了
class A<T extends B> {
public void fun(T t) {
}
}
class B {
A a;
public void event() {
a.fun(this);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是这会产生警告,因为A在B中定义但A已经将其用作泛型类型.
我的第一直觉是我的设计错了,但在这种情况下我无法改变它.A就像一个集合,B就像集合中的一个节点,用户应该覆盖它.某些事件可能发生在B中,需要向父母A报告.
但由于A一般用B定义,如何避免B.event()中的编译警告
谢谢
Lau*_*ves 13
问题是你在这一行上使用的是原始类型:
A a;
Run Code Online (Sandbox Code Playgroud)
您需要为A的类型参数(T)指定类型.
你可以这样做:
A<B> a;
Run Code Online (Sandbox Code Playgroud)
但是如果我理解你对这个问题的陈述,那么A根本就不是通用的.你可能想做这样的事情:
class A<T> {
public void fun(T t) {
}
}
class B<T extends B<T>> {
A<B<T>> a;
public void event() {
a.fun(this);
}
}
Run Code Online (Sandbox Code Playgroud)
甚至这个:
class A<T extends B<? extends T>> {
public void fun(T t) {
}
}
class B<T extends B<T>> {
A<? super B<T>> a;
public void event() {
a.fun(this);
}
}
Run Code Online (Sandbox Code Playgroud)
这些之间存在一些可能有用的变化.后一个例子是最通用的(但显然也是最复杂的).
该class A<T extends B<? extends T>>是确保类型参数A是B.由于B本身是通用的,并且具有循环类型的参数,你最终需要说B<? extends T>(只是说T将在这里工作).
的class B<T extends B<T>>,你可以得到在Java模拟一个"自我型"是接近.这让B谈论自己的(几乎)具体的子类型.当继承B时,你会说" class C extends <B<C>>" 这样的东西.这很有用,因为现在的类型C.a实际上是A<? super B<C>>.
? super后一个示例中的位仅在您计划将B连接到A不完全相同类型的B时才有用B.用具体的方式思考,假设你有一个A<Shape>和一个Circle(扩展Shape哪个扩展B).超级通配符允许您一起使用它们.没有它你需要一个A<Circle>而不是A<Shape>你的Circle.
Dav*_*vis 11
码
public class A<T extends B> {
public void fun(T t) {
}
}
public class B {
A<B> a;
public void event() {
a.fun(this);
}
}
Run Code Online (Sandbox Code Playgroud)
警告被打败了.
原因
A应使用特定的类类型声明类型的变量,如泛型类signature(A<T extends B>)所示.
解析度
虽然这解决了编译器警告,但潜在的问题仍然存在.劳伦斯为核心问题提供了出色的解释和解决方案.
| 归档时间: |
|
| 查看次数: |
1005 次 |
| 最近记录: |