use*_*911 3 java generics wildcard
所以我通过官方的java教程,https://docs.oracle.com/javase/tutorial/java/generics/index.html,也通过stackoverflow搜索,结果发现使用<E>和之间没有太大的区别<?>,一个我可以理解的是普通的通用形式,另一个是通配符.到目前为止,我遇到的唯一区别是,当使用<E>或<E extetnds BlaBlaClass>我们可以引用类型时E,否则我们根本不知道有关集合或数组或类型的任何信息.
我的问题是:使用<?>(通配符)优于普通泛型是否有任何优势<E>?如果是这样,这种情况的情况是什么?为什么有人会使用通配符呢?
我看过泛型类型和通配符类型之间的区别,区别?(通配符)和Java中的Type参数,何时使用泛型方法以及何时使用通配符?,Java泛型?,E和T有什么区别?.到目前为止,它似乎<?>是较差的版本<E>
无限通配符?在通用类型无关紧要的情况下非常有用.假设您有一个检查列表大小的方法,如果它太大,则清除它,并且您希望它接受包含任何类型元素的列表:
public static <E> void checkList(List<E> list, int max) {
if (list.size() > max) list.clear();
}
Run Code Online (Sandbox Code Playgroud)
您声明了类型变量E,但是size()和clear()方法不需要它,因此它未被使用.相反,你可以这样做:
public static void checkList(List<?> list, int max) {
if (list.size() > max) list.clear();
}
Run Code Online (Sandbox Code Playgroud)
这简化了方法声明,并使其他程序员明白此方法与列表元素的类型无关.
无界通配符也可用于字段或局部变量声明(其中不能声明类型变量),以允许使用任何泛型类型赋值.
public static void main(String[] args) {
List<?> list;
list = new ArrayList<Object>();
list = new ArrayList<String>();
list = new ArrayList<Integer>();
}
Run Code Online (Sandbox Code Playgroud)
如果是这样List<Object>,最后两行将无法编译.它可能是<? extends Object>,但这相当于<?>.
对于更实际的示例,假设您想要一个值可以是任何列表的映射:
public class MyClass {
public final Map<String, List<?>> lists = new HashMap<>();
}
Run Code Online (Sandbox Code Playgroud)
最后,如果您需要将值转换为泛型类,并且您不确定其类型参数,则必须使用?它们.(从不使用原始类型,它会禁用泛型类型的安全检查.)一个很好的例子就是常见的equals()实现:
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
MyClass<?> other = (MyClass<?>) obj;
if (!myField.equals(other.myField)) return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
有关Java泛型的更多信息,请查看Angelika Langer的泛型常见问题解答.
假设您正在使用某个 Foo 类的实例。
List<Foo>orList<? super Foo>但不能添加到 a List<?>or List<? extends Foo>。List<Foo>or获取它List<? extends Foo>,但不能从List<?>orList<? super Foo>获取它(它将返回为 Object)所以,这就是优点:您可以根据列表的 Foo 元素与列表进行交互。
如果您关心的是 List 是否为空,或者其他不依赖于其元素的特定形状的东西,那么 aList<?>就可以了。
这同样适用于您使用泛型方法并且正在处理泛型实例E而不是特定类 Foo 的情况:
public <E> void addIfEmpty(E element) {
List<? super E> listOfE = ...; // or List<E>
if (!listOfE.isEmpty()) {
listOfE.add(element);
}
List<?> listOfWild = ...;
if (!listOfWild.isEmpty()) {
listOfWild.add(element); // compilation error
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
969 次 |
| 最近记录: |