无法将泛型方法的结果传递给另一个方法? [英] Can't pass the result of a generic method to another method?

查看:189
本文介绍了无法将泛型方法的结果传递给另一个方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的泛型方法,创建一个n元素列表并返回它:

  import java.util。* ; 
class A {
public static< T>列表与LT; T> init(int n){
List< T> l = new ArrayList< T>();
while(n - > 0)l.add(null);
return l;
}
public static void main(String [] args){
List< String> x = init(5);
f(x);
}
public static void f(List< String> l){
System.out.println(l:+ l);


它符合预期:

  $ javac A.java&& java a 
l:[null,null,null,null,null]

但如果我消除额外的变量:

  import java.util。*; 
class A {
public static< T>列表与LT; T> init(int n){
List< T> l = new ArrayList< T>();
while(n - > 0)l.add(null);
return l;

public static void main(String [] args){
f(init(5));
}
public static void f(List< String> l){
System.out.println(l:+ l);


$ / code>

不再编译

  $ javac A.java&& (A)中的aa b $ b A.java:9:f(java.util.List< java.lang.String>)不能应用于(java.util.List< java.lang.Object>)
F(INIT(5));
^
1错误

为什么?



但是这样做:

  import java.util。*; 
class A {
public static< T>列表与LT; T> init(int n){
List< T> l = new ArrayList< T>();
while(n - > 0)l.add(null);
return l;
}
public static< T> T id(T t){
return t;
}
public static void main(String [] args){
List< String> x = init(5);
f(id(x));
}
public static void f(List< String> l){
System.out.println(l:+ l);


$ / code $ / pre

为什么?
<解决方案

在您的第一个示例中:

 列表< String> x = init(5); 
f(x);

编译器推断您正在调用< String> init 因为 x List< String>






在第二个例子中:

  f(的init(5)); 

编译器无法推断您正在调用< String>因为你没有明确地告诉它(通过 A。< String> init(5)),你也不会将它分配给适当的变量。






在第三个例子中:

 列表与LT;字符串> x = init(5); 
f(id(x));

编译器推断您正在调用< List< String>>
$ b




编译器对于泛型推理不太聪明。除非你明确指出类型参数是什么,不管是通过使用变量还是直接将它们传递给方法,它都无法解决它。



这里是JLS的相关部分,如果您对具体细节感兴趣:


I have a simple generic method that creates a list of n elements and returns it:

import java.util.*;
class A {
    public static <T> List<T> init(int n) {
        List<T> l = new ArrayList<T>();
        while (n --> 0) l.add(null);
        return l;
    }
    public static void main(String[] args) {
        List<String> x = init(5);
        f(x);
    }
    public static void f(List<String> l) {
        System.out.println("l: " + l);
    }
}

It works as expected:

$ javac A.java && java A
l: [null, null, null, null, null]

But if I eliminate the extra variable:

import java.util.*;
class A {
    public static <T> List<T> init(int n) {
        List<T> l = new ArrayList<T>();
        while (n --> 0) l.add(null);
        return l;
    }
    public static void main(String[] args) {
        f(init(5));
    }
    public static void f(List<String> l) {
        System.out.println("l: " + l);
    }
}

it no longer compiles

$ javac A.java && java A
A.java:9: f(java.util.List<java.lang.String>) in A cannot be applied to (java.util.List<java.lang.Object>)
        f(init(5));
        ^
1 error

Why?

But yet this works:

import java.util.*;
class A {
    public static <T> List<T> init(int n) {
        List<T> l = new ArrayList<T>();
        while (n --> 0) l.add(null);
        return l;
    }
    public static <T> T id(T t) {
        return t;
    }
    public static void main(String[] args) {
        List<String> x = init(5);
        f(id(x));
    }
    public static void f(List<String> l) {
        System.out.println("l: " + l);
    }
}

Why?

解决方案

Java relies on inference to figure out what the type variables are in a situation where they are not explicitly defined.

In your first example:

List<String> x = init(5);
f(x);

The compiler infers that you are calling <String> init because x is a List<String>.


In your second example:

f(init(5));

The compiler cannot infer that you are calling <String> init because you are not explicitly telling it (via A. <String> init(5)) nor are you assigning it to an appropriate variable.


In your third example:

List<String> x = init(5);
f(id(x));

The compiler infers that you are calling <List<String>> id which returns a List<String> to f.


The compiler isn't too smart about generic inference. Unless you explicitly state what the type arguments are, either by using a variable or by directly passing them to the method, it will not be able to figure them out.

Here are the relevant sections of the JLS if you're curious about the specifics:

这篇关于无法将泛型方法的结果传递给另一个方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆