当前位置: 首页 > 知识库问答 >
问题:

泛型。使用通配符``vs使用类型参数``

通啸
2023-03-14

所以我看了官方的java教程,https://docs.oracle.com/javase/tutorial/java/generics/index.html,也搜索了stackoverflow,结果发现使用没有太大区别

我的问题是:使用有什么好处吗?

我已经研究了泛型类型和通配符类型之间的区别,它们之间的区别是什么?(通配符)和类型参数,何时使用泛型方法,何时使用通配符,Java泛型,E和T有什么区别。到目前为止,它看起来像是<代码>


共有2个答案

杜曜灿
2023-03-14

假设您正在处理某个类Foo的实例。

  • 如果您有Foo,您可以将其添加到列表中

因此,这就是优点:可以根据列表的Foo元素与列表交互。

如果您只关心列表是否为空,或者不依赖于其元素的特定形状的其他内容,那么

这同样适用于您处于泛型方法中,并且正在处理泛型而非特定类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
    }
}

蒋无尘
2023-03-14

无界通配符 在泛型类型无关紧要的情况下很有用。假设您有一个方法,可以检查列表的大小,如果列表太大,则将其清除,并希望它接受包含任何类型元素的列表:

public static <E> void checkList(List<E> list, int max) {
    if (list.size() > max) list.clear();
}

您声明了类型变量E,但size()Clear()方法不需要它,因此它不会被使用。相反,您可以这样做:

public static void checkList(List<?> list, int max) {
    if (list.size() > max) list.clear();
}

这简化了方法声明,并向其他程序员清楚地表明,该方法与列表元素的类型无关。

无界通配符也可以在字段或局部变量声明(无法声明类型变量)中使用,以允许使用任何泛型类型赋值。

public static void main(String[] args) {
    List<?> list;
    list = new ArrayList<Object>();
    list = new ArrayList<String>();
    list = new ArrayList<Integer>();
}

如果这是列表

举一个更实际的例子,假设您想要一个地图,其中的值可以是任何列表:

public class MyClass {
    public final Map<String, List<?>> lists = new HashMap<>();
}

最后,如果您需要将值强制转换为泛型类并且不确定其类型参数,则必须使用。(永远不要使用原始类型,它会禁用泛型类型安全检查。)一个很好的例子是常见的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;
}

有关Java泛型的更多信息,请查看Angelika Langer的泛型常见问题解答。

 类似资料:
  • 我正在刷新我关于Java泛型的知识。所以我转向甲骨文的优秀教程...并开始为我的同事准备一个演示文稿。我在教程中遇到了通配符部分,上面写着: 考虑以下方法,打印列表: printList的目标是打印任何类型的列表,但它无法实现该目标-它只打印对象实例的列表;无法打印列表 我明白那个

  • 在了解Java泛型的过程中,我遇到了以下问题: 假设我有下面的方法来添加列表的元素,只限于包含数字的列表。 但是这段代码和这段代码有什么不同: 它们都按预期编译和执行。这两者之间有什么区别?除了语法之外?什么时候我更喜欢使用通配符而不是前者? 是的,使用通配符方法,我不能在列表中添加除null之外的新元素,否则它将无法编译。除此之外呢?

  • 问题内容: 我试图理解Java泛型,它们似乎很难理解。例如,这很好… …就是这个… … 还有这个 … …但是不能编译: 有人可以用简单的语言解释发生了什么吗? 问题答案: 对于泛型类型,主要要了解的是它们不是协变的。 因此,尽管您可以这样做: 以下内容将无法编译: 这是为了避免您绕过通用类型的情况: 因此,一一讲解您的示例 1个 您的通用方法采用a ,而您采用;(基本上是)。可以分配给类型,并且编

  • 此外,是否可以说泛型通配符类型仅在方法的参数声明中才有意义?

  • 这2个功能有什么区别? 我看到了相同的输出。

  • 问题内容: 我正在刷新有关Java泛型的知识。因此,我转向了Oracle的优秀教程……并开始为我的同事编写一个演示文稿。我在本教程中遇到了有关通配符的部分,内容为: 考虑以下方法,printList: printList的目标是打印任何类型的列表,但未能实现该目标- 它仅打印Object实例的列表;它不能打印,,,等等,因为它们不是的亚型。要编写通用的printList方法,请使用: 我知道那是行