Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 泛型方法调用_Java_Generics - Fatal编程技术网

Java 泛型方法调用

Java 泛型方法调用,java,generics,Java,Generics,我一直在尝试泛型,很快我就遇到了无法解释的问题。 例如: import java.util.*; public class Main { public static void main(String[] args) { //We cannot create List<?> l = new ArrayList<?>(); List<?> l = MagicClass.factory(); } static

我一直在尝试泛型,很快我就遇到了无法解释的问题。
例如

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>();
        }
    }
}
import java.util.*;
公共班机{
公共静态void main(字符串[]args){
//无法创建列表l=new ArrayList();
列表l=MagicClass.factory();
}
静态类MagicClass{
公共静态列表工厂(){
返回新的ArrayList();
}
}
}
我不明白为什么
可以是显式类型参数,而这个

<?>

是未定义的。

是一个,它的意思相当于:“您喜欢的任何类型”。现在由于
因此没有对所使用的类型进行任何假设,
t
只能更专业化。因此Java将
Foo
视为
Foo
。另一方面,这样做是不明智的,因为Java对代码进行类型检查的手段较少。因此,Java通常会拒绝将类型参数用作输入的任何方法

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

    ArrayList<?> foo = new ArrayList<String>();
    foo.add("bar");
ArrayList<?> foo = new ArrayList<?>();
这是因为在构建时,Java必须知道您将选择哪种类型


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

public void drawAll(List<? extends Shape> shapes) {
    //...
}
public void drawAll(List
是一个,它的意思是:“您喜欢的任何类型”现在,由于
因此没有对所使用的类型进行任何假设,
t
只能更专业化。因此,Java将
Foo
视为
Foo
。另一方面这样做是不明智的,因为Java对代码进行类型检查的手段较少。因此,Java通常会拒绝向任何meth>开具发票类型参数用作输入的od

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

    ArrayList<?> foo = new ArrayList<String>();
    foo.add("bar");
ArrayList<?> foo = new ArrayList<?>();
这是因为在构建时,Java必须知道您将选择哪种类型


但在许多情况下,它被用作有界通配符。例如:

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

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

以下内容也提到了这一点:

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


另一方面,在
工厂
方法中,
T
是一个类型参数,将由编译器推断,并且由于
列表
表示任何类型,编译器接受它。

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

以下内容也提到了这一点:

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

另一方面,在
工厂
方法中,
T
是编译器将推断的类型参数,并且由于
列表
表示任何类型,因此编译器接受它

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

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

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

listl=newarraylist();

listl=newarraylist();

listl=newarraylist();
所有这些都是正确的。只需选择满足边界的任何类型;它甚至不必与您正在做的事情相关

从这一点,你可以看出为什么你试图做的事情是荒谬的——你有一个列表,可以是
ArrayList
,也可以是
ArrayList
(你不知道)。那么你能用它做些什么呢?不多

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

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

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

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

listl=newarraylist();

listl=newarraylist();

listl=newarraylist();
所有这些都是正确的。只需选择满足边界的任何类型;它甚至不必与您正在做的事情相关

从这一点,你可以看出为什么你试图做的事情是荒谬的——你有一个列表,可以是
ArrayList
,也可以是
ArrayList
(你不知道)。那么你能用它做些什么呢?不多


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

如何在factory()方法中明确表示,
t
可以是