Java 什么时候参数化方法调用有用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2781672/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 12:47:57  来源:igfitidea点击:

When is a parameterized method call useful?

javagenericsparametersmethodscall

提问by Johann-Christoph Jacob

A Java method call may be parameterized like in the following code:

Java 方法调用可以像下面的代码一样参数化:

class Test
{
    <T> void test()
    {
    }

    public static void main(String[] args)
    {
        new Test().<Object>test();
        //         ^^^^^^^^
    }
}

I found out this is possible from the Eclipse Java Formatter settings dialog and wondered if there are any cases where this is useful or required.

我从 Eclipse Java Formatter 设置对话框中发现这是可能的,并想知道是否有任何有用或必需的情况。



EDIT

编辑

Based on Arne's excellent answer i came up with the following conclusion:

基于 Arne 的出色回答,我得出以下结论:

In addition to improved type safety as Arne's example illustrates a parameterized method call enables you to specify the common base type of the methods arguments that should be the type of the container elements. This type is normally inferenced automatically by the compiler to the most specific common base type. By parameterizing the method call this behaviour may be overridden. A parameterized method call may be required if there are multiple common types inferenced by the compiler.

除了 Arne 的示例说明的改进的类型安全性之外,参数化方法调用使您能够指定方法参数的公共基类型,该类型应该是容器元素的类型。这种类型通常由编译器自动推断为最具体的常见基类型。通过参数化方法调用,这种行为可能会被覆盖。如果编译器推断出多种常见类型,则可能需要参数化方法调用。

The following example demonstrates that behaviour:

以下示例演示了该行为:

import java.util.Arrays;
import java.util.List;

class Test
{
    public static void main(String[] args)
    {
        Integer a=new Integer(0);
        Long    b=new Long(0);
        List<Object> listError=Arrays.asList(a, b);
        //error because Number&Comparable<?> is not Object
        List<Object> listObj=Arrays.<Object>asList(a, b);
        List<Number> listNum=Arrays.<Number>asList(a, b);
        List<Comparable<?>> listCmp=Arrays.<Comparable<?>>asList(a, b);
    }
}

This behaviour is defined in The Java Language Specification Third Edition paragraphs 8.4.4 and 15.12.2.7 but not easily understood.

此行为在 Java 语言规范第三版第 8.4.4 和 15.12.2.7 段中定义,但不容易理解。

采纳答案by Arne Deutsch

I never have used this in practice, but you can imagine to use this for type safety. Consider the following method:

我从未在实践中使用过它,但你可以想象将它用于类型安全。考虑以下方法:

<T> void method(T... items) {
    List<T> list = new ArrayList<T>();
    for (T item : items)
        list.add(item);
    System.out.println(list);
}

You can call it this way:

你可以这样称呼它:

o.<Object>method("Blah", new Long(0));
o.<Number>method(new Integer(100), new Long(0));

But this will raise an compiler error:

但这会引发编译器错误:

o.<Number>method("String", new Long(0));

So you have an generic method that is typesafe and can be used for every Object, not limited to a paricular interface or class.

所以你有一个类型安全的泛型方法,可以用于每个对象,不限于特定的接口或类。

回答by ILMTitan

It is probably most useful when you are taking a collection of some type, and returning some subset of that collection.

当您获取某种类型的集合并返回该集合的某个子集时,它可能最有用。

<T> List<T> filter(Collection<? extends T> coll, Predicate<? super T> pred) {
    List<T> returnList = new ArrayList<T>();
    for(T t : coll) {
        if(pred.matches(t)){
            returnList.add(t);
        }
    }
    return returnList;
}


Edit:

编辑:

More generally, it is useful whenever you wish to return a specific type, or you want to link the types of two or more parameters in a general way.

更一般地说,当您希望返回特定类型或希望以通用方式链接两个或多个参数的类型时,它很有用。

回答by justkt

Parameterized method calls are useful when you want to allow different types without casting. For example, the Collectionshelper class makes extensive use of parameterized method calls. When you want to make a new generic collection using one of their helper methods, a few examples:

当您希望允许不同类型而不进行强制转换时,参数化方法调用非常有用。例如,Collections助手类广泛使用参数化方法调用。当你想使用他们的帮助方法之一创建一个新的泛型集合时,举几个例子:

List<String> anEmptyStringList = Collections.<String>emptyList();
Set<Integer> unmodifiableCopy = Collections.<Integer>unmodifiableSet(originalSet);

So, when you want to be able to use the generic type elsewhere, you want to use those method calls. They prevent compiler warnings when using generics.

因此,当您希望能够在其他地方使用泛型类型时,您希望使用这些方法调用。它们在使用泛型时防止编译器警告。

回答by Aleksejs Mjaliks

For example, when you need some universalmethod for comparisons:

例如,当您需要一些通用的比较方法时:

public static <T extends Comparable> T max(T one, T two) {
    if (one.compareTo(two) > 0) {
        return one;
    } else {
        return two;
    }
}