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

泛型方法调用

夔波
2023-03-14

我一直在尝试泛型,很快我就遇到了一些我无法解释的事情
例如:

import java.util.*;
public class Main {
    public static void main(String[] args) {
        //We cannot create List<?> l = new ArrayList<?>();
        List<?> l = MagicClass.factory();
    }
    static class MagicClass {
        public static <T> List<T> factory() {
            return new ArrayList<T>();
        }
    }
}

我不明白

<?>

没有定义。


共有3个答案

元叶秋
2023-03-14

我们无法创建列表l=new ArrayList();

如果你真的想做,你可以做

List<?> l = new ArrayList<Object>();

或者

List<?> l = new ArrayList<String>();

或者

List<?> l = new ArrayList<Math>();

或者

List<?> l = new ArrayList<SomeBogusIrrelevantClass>();

所有这些都是正确的。只要选择满足边界的任何类型;它甚至不需要与你正在做的事情相关。

从这里,你可以看出为什么你试图做的事情是荒谬的——你有一个列表可以是ArrayList

您不能向其添加任何内容(除了null)。所以你有一个列表,其中元素只能有值null;唯一可以改变的是有多少个nulls。但在这种情况下,您最好使用一个整数。

柯瀚海
2023-03-14

示例:以下代码无法编译:

    ArrayList<?> foo = new ArrayList<String>();
    foo.add("bar");

这是因为Java不知道foo中的t是什么。foo可能是ArrayList

例如,如果你想制作一个可以接受各种列表的方法,就可以使用它

永远不能用通配符构造实例

以下代码无法编译:

ArrayList<?> foo = new ArrayList<?>();

这是因为在施工时,Java必须知道你会选择哪种类型。

但在许多情况下,它被用作有界通配符。举个典型的例子:

public void drawAll(List<? extends Shape> shapes) {
    //...
}

这个方法给出了一个Shape的列表

长孙智刚
2023-03-14

使用通配符实例化泛型类型会生成编译错误,因为通配符表示任何类型,而实例化的ArrayList应该有一个具体的类型。通配符可以用于变量或参数类型,但不能用于创建泛型类型的实例。

本教程页面也提到了这一点:

在泛型代码中,问号(),称为通配符,表示未知类型。通配符可以在多种情况下使用:作为参数、字段或局部变量的类型;有时作为返回类型(尽管编程实践中最好更具体)。通配符永远不会用作泛型方法调用、泛型类实例创建或超类型的类型参数。

另一方面,在工厂方法中,T是编译器将推断的类型参数,并且由于List

 类似资料:
  • 问题内容: 我遇到了一个涉及静态泛型方法的奇怪情况。这是代码: 我为什么不必在表达式中指定任何类型参数?这是某种类型推断吗?如果我想对此进行明确说明,如何指定类型参数? 问题答案: 是的,根据JLS第15.12.2.8节,这是基于分配目标的类型推断。明确地说,您可以这样称呼:

  • 我有Java8 Groovy 2.4.12和下面的代码编译和运行。 但是如果你注释掉< code>return,编译器会说 此外,如果您注释掉值分配,那么它又可以了。因此,下面的代码编译并运行: 这似乎是一种特殊情况,只有在以下情况下才会发生: 注释 具有两个参数的泛型方法;第一个是泛型类型,第二个是相同泛型类型的接口 调用该泛型方法,第二个参数作为闭包,全部包装在另一个闭包中。 调用前的变量声明

  • 问题内容: 没有静态成员可以使用类型参数,但是可以使用泛型类型参数调用静态成员吗​​?例如:- 这里的add()是一个静态方法。 在类似的主题上也有一些C#问题和答案,但是我不太确定如何在Java中使用它。 问题答案: 不,如果A是泛型类型,则无法执行。(Bozho对fast的回答是:),可能认为A是具体类型。 可行的方法如下。 但这可能不是您想要的。 阅读您的评论后,听起来您真正想要做的是: 您

  • 问题内容: 我想知道用这样的签名调用静态方法的正确方法是什么: 由于某种原因,我很想这样称呼它: 但是除非我将其更改为:否则它不会编译: 我只是想知道为什么它不需要右侧的提示。而是给了我编译错误。它说它期望在右侧的提示后加上分号。第二个方法是调用该方法的正确方法吗?有人可以给我一些启示吗? 问题答案: 如图所示这里,要调用的方法的方法是: 该方法所在的类的名称在哪里。

  • 安吉丽卡·兰格(Angelica Langer)在关于仿制药的常见问题解答中说(参见Technicalities.FAQ822): 如果这些方法具有具有不同边界的类型参数,则它们不会重写,因为这些方法的签名不是重写等价的。请记住,类型参数边界是泛型方法签名的一部分。 示例(泛型子类型方法重载泛型超类型方法;不推荐): 我不明白为什么方法在类中重载。据我所知,这应该是一个编译时错误,因为在和中具有相

  • 我有一个Foo和Bar对象的列表,以及每个相应对象的转换器。 Convert-method需要有所不同,因为Bar1与Bar2和Bar3等有很大不同,但是我想创建一个方法来处理所有可能的列表。 是否可以创建一个泛型方法,根据列表的内容调用相应的非泛型方法? 到目前为止,我已经尝试过了: 但这并不能编译,因为"无法解析方法'Converts(T, S)'" 有什么想法吗?