如何使 Java 通用方法静态化?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4409100/
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-14 17:09:17  来源:igfitidea点击:

How to make a Java Generic method static?

javagenerics

提问by Chris Johnson

The following is a snippet on how to make a java generic class to append a single item to an array. How can I make appendToArray a static method. Adding static to the method signature results in compile errors.

以下是关于如何使 Java 泛型类将单个项目附加到数组的片段。如何使 appendToArray 成为静态方法。向方法签名添加静态会导致编译错误。

public class ArrayUtils<E> {

        public E[] appendToArray(E[] array, E item) {
            E[] result = (E[])new Object[array.length+1];
            result[array.length] = item;
            return result;
        }
}

采纳答案by scheffield

the only thing you can do is to change your signature to

你唯一能做的就是把你的签名改成

public static <E> E[] appendToArray(E[] array, E item)

Important details:

重要细节:

Generic expressions preceding the return value always introduce (declare) a new generic type variable.

返回值之前的泛型表达式总是引入(声明)一个新的泛型类型变量。

Additionally, type variables between types (ArrayUtils) and static methods (appendToArray) never interfere with each other.

此外,类型 ( ArrayUtils) 和静态方法 ( appendToArray)之间的类型变量永远不会相互干扰。

So, what does this mean: In my answer <E>would hide the Efrom ArrayUtils<E>if the method wouldn't be static. AND <E>has nothing to do with the Efrom ArrayUtils<E>.

那么,这是什么意思:在我的回答<E>EArrayUtils<E>如果方法不是static. AND<E>Efrom无关ArrayUtils<E>

To reflect this fact better, a more correct answer would be:

为了更好地反映这一事实,更正确的答案是:

public static <I> I[] appendToArray(I[] array, I item)

回答by axtavt

You need to move type parameter to the method level to indicate that you have a generic method rather than generic class:

您需要将类型参数移动到方法级别以表明您有一个泛型方法而不是泛型类:

public class ArrayUtils {
    public static <T> E[] appendToArray(E[] array, E item) {
        E[] result = (E[])new Object[array.length+1];
        result[array.length] = item;
        return result;
    }
}

回答by Bert F

public static <E> E[] appendToArray(E[] array, E item) { ...

Note the <E>.

请注意<E>.

Static generic methods need their own generic declaration (public static <E>) separate from the class's generic declaration (public class ArrayUtils<E>).

静态泛型方法需要它们自己的泛型声明 ( public static <E>) 与类的泛型声明 ( public class ArrayUtils<E>)分开。

If the compiler complains about a type ambiguity in invoking a static generic method (again not likely in your case, but, generally speaking, just in case), here's how to explicitly invoke a static generic method using a specific type (_class_.<_generictypeparams_>_methodname_):

如果编译器在调用静态泛型方法时抱怨类型歧义(在您的情况下也不太可能,但一般来说,以防万一),以下是使用特定类型 ( _class_.<_generictypeparams_>_methodname_)显式调用静态泛型方法的方法:

String[] newStrings = ArrayUtils.<String>appendToArray(strings, "another string");

This would only happen if the compiler can't determine the generic type because, e.g. the generic type isn't related to the method arguments.

这只会在编译器无法确定泛型类型时发生,因为例如泛型类型与方法参数无关。

回答by Vishnu Vivek

I'll explain it in a simple way.

我会用简单的方式解释它。

Generics defined at Class level are completely separate from the generics defined at the (static) method level.

在类级别定义的泛型与在(静态)方法级别定义的泛型完全分开。

class Greet<T> {

    public static <T> void sayHello(T obj) {
        System.out.println("Hello " + obj);
    }
}

When you see the above code anywhere, please note that the T defined at the class level has nothing to do with the T defined in the static method. The following code is also completely valid and equivalent to the above code.

当你在任何地方看到上面的代码时,请注意在类级别定义的 T 与静态方法中定义的 T 无关。下面的代码也是完全有效的,等价于上面的代码。

class Greet<T> {

    public static <E> void sayHello(E obj) {
        System.out.println("Hello " + obj);
    }
}

Why the static method needs to have its own generics separate from those of the Class?

为什么静态方法需要有自己的泛型与类的泛型分开?

This is because, the static method can be called without even instantiating the Class. So if the Class is not yet instantiated, we do not yet know what is T. This is the reason why the static methods needs to have its own generics.

这是因为,甚至可以在不实例化 Class 的情况下调用静态方法。所以如果Class还没有被实例化,我们还不知道什么是T。这就是静态方法需要有自己的泛型的原因。

So, whenever you are calling the static method,

因此,每当您调用静态方法时,

Greet.sayHello("Bob");
Greet.sayHello(123);

JVM interprets it as the following.

JVM 将其解释如下。

Greet.<String>sayHello("Bob");
Greet.<Integer>sayHello(123);

Both giving the same outputs.

两者都给出相同的输出。

Hello Bob
Hello 123