在某些情况下而不是其他情况下如何隐式绑定参数化方法? - java

我最近重构代码时遇到了这个问题:

下面的方法“getList()”具有参数化的返回类型。在此之下,我放置了三种方法,这些方法试图将<T>隐式绑定到<Integer>

我不知道为什么前两个编译并正确运行,而第三个(bindViaMethodInvocation)甚至无法编译。

有什么线索吗?

在寻找关于StackOverflow的类似问题时,我遇到了这个问题:
Inferred wildcard generics in return type。那里的答案(credit Laurence Gonsalves)有几个有用的参考链接来解释应该发生的情况:
“这里的问题(如您建议的那样)是编译器正在执行Capture Conversion。我相信这是JLS的§15.12.2.6 of the JLS的结果。”

package stackoverflow;

import java.util.*;

public class ParameterizedReturn
{
    // Parameterized method
    public static <T extends Object> List<T> getList()
    {
        return new ArrayList<T>();
    }

    public static List<Integer> bindViaReturnStatement()
    {
        return getList();
    }

    public static List<Integer> bindViaVariableAssignment()
    {
        List<Integer> intList = getList();
        return intList;
    }

    public static List<Integer> bindViaMethodInvocation()
    {
        // Compile error here
        return echo(getList());
    }

    public static List<Integer> echo(List<Integer> intList)
    {
        return intList;
    }
}

参考方案

前两个方法在要进行赋值转换的上下文中使用getList() -分配给List<Integer>或返回List<Integer>的方法的return语句。 bindViaMethodInvocation并非如此-使用表达式作为方法参数不需进行赋值转换。

从JLS section 15.12.2.8:

如果没有从实际参数的类型中推断出方法的任何类型参数,则现在可以按以下方式进行推断。

  • 如果方法结果发生在将要进行赋值转换(第5.2节)为S类型的上下文中,则令R为方法的声明结果类型,令R'= R [T1 = B(T1 )... Tn = B(Tn)]其中B(Ti)是上一节中为Ti推断的类型,如果没有推断出类型,则为Ti。
  • JLS对于返回语句为什么要在此处计数还不清楚。我能找到的最接近的是14.17:

    带有表达式的return语句必须包含在声明为返回值(第8.4节)的方法声明中,否则会发生编译时错误。表达式必须表示某个类型T的变量或值,否则会发生编译时错误。类型T必须可分配给方法的声明结果类型(第5.2节),否则会发生编译时错误。

    (如果第5.2节指出return语句可以进行赋值转换,那就太好了。)

    Java中的<<或>>>是什么意思? - java

    This question already has answers here: Closed 7 years ago. Possible Duplicate: What does >> and >>> mean in Java?我在一些Java代码中遇到了一些陌生的符号,尽管代码可以正确编译和运行,但对于括号在此代码中的作用却感…

    与哪些运算符>>兼容 - java

    我这里没有什么代码int b=3; b=b >> 1; System.out.println(b); 它可以完美工作,但是当我将变量b更改为byte,short,float,double时,它包含错误,但是对于变量int和long来说,它可以完美工作,为什么它不能与其他变量一起工作? 参考方案 位移位运算符(例如>>)与任何整数类型兼…

    菱形运算符<>是否等于<?> - java

    我在util.TreeSet类中发现,其中一个构造函数正在使用具有空泛型类型的新TreeMap调用另一个构造函数。 public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); } new TreeMap<>是什么意思…

    Java中的“ <<”运算符 - java

    最喜欢的语句来自Java的Character类:(1 << Character.PARAGRAPH_SEPARATOR)) >> type PARAGRAPH_SEPARATOR是字节,type是整数。这句话中的操作员,他们做什么?如何以及在哪里可以使用这些运算符?这是oracles java.lang.Character文档。该类中…

    通过Maven编译器插件不会发生有限的包含和排除 - java

    我正在使用3.6.0版的maven编译器插件,在此我们只想在特定文件夹中编译一个文件,而在该位置编译所有其他文件。例如:在文件夹应用程序中有14个文件,从那我只希望编译1个文件,但它编译了所有文件,如果我要排除,则它也不起作用。 <sourceDirectory>${basedir}/../src/java</sourceDirectory…