2010-12-10 192 views
117

以下是关于如何使Java泛型类将单个项目追加到数组的一个片段。我怎样才能让appendToArray成为一个静态方法。将静态添加到方法签名会导致编译错误。如何使Java通用方法静态?

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

你会得到什么编译错误?另外,为什么不使用标准库容器之一? – 2010-12-10 13:08:09

+1

编译错误:我实际上是添加了静态修饰符不正确。使用集合:是使用集合是理想的,但问题不在于集合与数组的关系,我的用例需要数组。 – 2010-12-10 13:30:54

+0

请注意,您需要使用(EVIL)反射来停止客户端代码在某些情况下抛出异常,但不是所有情况(很好)。最好避免使用参考数组。 – 2010-12-10 14:26:09

回答

210

,你唯一可以做的事情就是你的签名更改为

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

重要细节:

通用表达式返回值前总是介绍(声明)一个新的通用型变量。

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

那么,这是什么意思: 在我的答案<E>将从ArrayUtils<E>隐藏E如果该方法不会static。 AND <E>ArrayUtils<E>E无关。

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

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

请注意,类级别类型变量“E”与静态方法类型变量“E”之间绝对没有关系。我认为在泛型类中声明静态或其他方法时使用不同的变量名是更好的做法。 – 2013-10-04 03:34:16

+0

但在这种情况下,我可以将一个不同类型的对象传递给params。就像我可以传递Integer []数组作为第一个参数和双项。 – pinkpanther 2015-05-20 08:50:54

+0

pinkpanther:是的,但它没有任何伤害,因为静态方法只对通过参数传递给它的数组对象进行操作,所以它的元素肯定有正确的类型。 – Dabbler 2016-08-22 19:19:14

7

你需要输入参数移到方法水平,表明你有一个通用的方法,而不是通用类:

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; 
    } 
} 
57
public static <E> E[] appendToArray(E[] array, E item) { ... 

请注意<E>

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

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

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

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