2012-08-09 116 views
5

我想知道只有当方法是静态时才使用泛型方法吗?对于非静态的你可以定义一个泛型类,你不需要它是通用的方法。那是对的吗 ?Java:泛型方法只与静态?

例如,

public class Example<E>{ 

     //this is suffice with no compiler error 
     public void doSomething(E [] arr){ 
       for(E item : arr){ 
        System.out.println(item); 
       } 
     } 

     //this wouldn't be wrong, but is it necessary ? 
     public <E> doSomething(E [] arr){ 
       for(E item : arr){ 
        System.out.println(item); 
       } 
     } 
    } 

,而编译器将强制添加类型参数,使其成为通用的方法,如果它是静态的。

public static <E> doSomething(E [] arr){ 


    } 

我不知道我是否正确。

+4

你也可以拥有通用的实例方法,而不需要使你的类成为通用的。 – 2012-08-09 14:17:19

回答

4
public class Example<E>{ 

为实例的方法和字段定义了一个通用类型。

public void <E> doSomething(E [] arr){ 

这定义了第二个E,它与第一个不同,可能会造成混淆。

注:void仍需要;)

静态字段和方法不使用泛型类的。

public static <F> doSomething(F [] arr) { } 

private static final List<E> list = new ArrayList<>(); // will not compile. 
+0

静态字段和方法不使用类的通用类型。这是为什么 ? – peter 2012-08-09 14:31:44

+0

类的每个实例都可以具有不同的通用类型。这对静态成员没有意义。 – 2012-08-09 14:33:29

+0

非静态字段和方法呢?他们是否共享班级的通用类型?我的意思是他们必须? – peter 2012-08-09 14:43:42

3

假设您声明Example<String> example = new Example<String>();

  • public void doSomething(E [] arr)将期待一String[]参数
  • public <E> void doSomething(E [] arr)将期望的任何类型的阵列(它是不一样的EExample<E>
  • public static <E> void doSomething(E [] arr)将期望的任何类型的阵列

在任何情况下,由于您的Example<E>可以参数化,所以您不能在该静态调用中使用该E,因为它将与实例相关。这有点像从静态方法中调用非静态成员。所以你必须在本地重新定义它。

+0

你可以例如创建一个'Example ',然后创建一个'Example '。静态方法与特定实例无关,但与类相关。所以静态方法无法解决'E',因为可能有几个。 – assylias 2012-08-09 14:38:16

+0

我的比喻是,如果你有一个'private String abc;'(一个实例字段),你不能从静态方法访问它,因为每个类的实例都有一个'abc'字符串。 – assylias 2012-08-09 14:39:06

+0

那么在这种情况下,我必须使用E以外的其他东西吗?如果我使用E,它会给编译器错误吗?你在本地重新定义它的意义是什么 – peter 2012-08-09 14:40:03

0

考虑接口java.util.Collection。它被声明为:

public interface Collection<E>{ 
    //... 
    <T> T[] toArray(T[] a); 
} 

toArray是使用类型参数T,这与从接口声明的类型参数E没有任何关系的普通实例方法。

这是JDK本身的一个很好的例子,它说明了使用泛型实例方法的价值。