下面是一个关于如何创建java泛型类来将单个项附加到数组的代码片段。如何使appendToArray成为静态方法。将static添加到方法签名中会导致编译错误。

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;
        }
}

当前回答

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

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

重要的细节:

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

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

那么,这意味着什么呢? 在我的回答中,如果方法不是静态的,<E>将从ArrayUtils<E>中隐藏E。AND <E>与ArrayUtils<E>中的E无关。

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

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

其他回答

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

注意<E>。

静态泛型方法需要独立于类的泛型声明(公共类ArrayUtils<E>)的泛型声明(公共类Static <E>)。

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

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

这只会发生在编译器无法确定泛型类型的情况下,例如,泛型类型与方法参数无关。

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

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;
    }
}

如何使appendToArray成为静态方法?

要使它成为静态的,你需要:

添加静态修饰符 将泛型类型E添加到方法签名中

特别是对于你的例子,这意味着改变方法签名:

public E[] appendToArray(E[] array, E item) {

:

// same as above, but with "static <E>" before return type E[]
public static <E> E[] appendToArray(E[] array, E item) {

很容易忽略的关键部分:泛型类型应该添加到签名中,出现在返回类型之前。以下节选自 Java泛型方法教程:

Generic methods are methods that introduce their own type parameters. This is similar to declaring a generic type, but the type parameter's scope is limited to the method where it is declared. Static and non-static generic methods are allowed, as well as generic class constructors. The syntax for a generic method includes a list of type parameters, inside angle brackets, which appears before the method's return type. For static generic methods, the type parameter section must appear before the method's return type.

我用简单的方式解释一下。

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

class Greet<T> {

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

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

class Greet<T> {

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

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

这是因为,静态方法可以被调用 实例化类。所以如果Class还没有实例化,我们 还不知道t是什么,这就是为什么采用静态方法的原因吗 需要有自己的泛型。

当你调用静态方法时,

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

JVM将其解释如下。

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

两者都给出相同的输出。

Hello Bob
Hello 123

从javadoc

泛型方法

泛型方法是引入自己的类型参数的方法。这类似于声明泛型类型,但类型参数的作用域仅限于声明它的方法。允许使用静态和非静态泛型方法,以及泛型类构造函数。

泛型方法的语法包括一个类型参数列表,位于尖括号内,出现在方法的返回类型之前。对于静态泛型方法,类型参数段必须出现在方法的返回类型之前。

Util类包含一个泛型方法compare,用于比较两个Pair对象:

public class Util {
    public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
}


public class Pair<K, V> {

private K key;
private V value;

public Pair(K key, V value) {
    this.key = key;
    this.value = value;
}

public void setKey(K key) { this.key = key; }
public void setValue(V value) { this.value = value; }
public K getKey()   { return key; }
public V getValue() { return value; }
}

调用这个方法的完整语法是:

Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.<Integer, String>compare(p1, p2);

类型已显式地提供,如粗体所示。一般来说,这个可以省略,编译器会推断出需要的类型:

Pair<Integer, String> p1 = new Pair<>(1, "apple");
Pair<Integer, String> p2 = new Pair<>(2, "pear");
boolean same = Util.compare(p1, p2);

这个特性称为类型推断,允许您将泛型方法作为普通方法调用,而不需要在尖括号之间指定类型。

在理解了这个文档之后,对于你的问题答案是:

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