1. 泛型方法
泛型方法所属的类,可能是泛型类,也可能是普通类。
比如 Collection接口中的泛型方法 toArray 泛型方法中的泛型类型 T 泛型类的泛型类型E
public interface Collection<E> extends Iterable<E> {
// ...
<T> T[] toArray(T[] a);
// ...
// 类似以下方法,不是泛型方法,只是使用了类的泛型
Iterator<E> iterator();
default Stream<E> stream() {return StreamSupport.stream(spliterator(), false);}
}
泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系。
泛型方法,可以声明为静态的。原因:泛型参数是在调用方法时确定的。并非在实例化类时确定。调用方法的时候,指定泛型方法中的泛型类型
2. 写泛型方法的正确姿势
1. 首先希望传入方法transFromArrayToList的参数是一个泛型类型的数组,泛型类型为E
public List transFromArrayToList(E[] array){
return null;
}
2. 数组类型是E[] ,那么返回的List类型就是 List<E>
public List<E> transFromArrayToList(E[] array){
return null;
}
3. 上面的写法还是会有歧义, 如果E就是个类类型(class)呢?编译器无法判断
如果恰好有个类的名字就是E,那么这个方法就不是泛型方法了。所以在上面的写法基础上在加上点标识 <E>
public <E> List<E> transFromArrayToList(E[] array){
return null;
}
OK,此时的transFromArrayToList就完全是一个泛型方法了。
完整的代码示例:
//GenericMethodTest1.java
package com.ylaihui.generic;
import java.util.ArrayList;
import java.util.List;
class Computer<T>{
int id;
String name;
T extendInfo;
public <E> List<E> transFromArrayToList(E[] array){
ArrayList<E> es = new ArrayList<E>();
for (int i = 0; i <array.length; i++) {
es.add(array[i]);
}
return es;
}
public static <E> List<E> statictransFromArrayToList(E[] array){
ArrayList<E> es = new ArrayList<E>();
for (int i = 0; i <array.length; i++) {
es.add(array[i]);
}
return es;
}
}
public class GenericMethodTest1 {
public static void main(String[] args) {
// 实例化泛型类的时候,指明泛型参数为 Double
Computer<Double> dc = new Computer<>();
Boolean[] bls = new Boolean[]{true, false, true, false};
// 调用泛型方法 transFromArrayToList 时,指定了泛型参数 Boolean
// 意味着 在方法中出现了泛型的结构,方法的泛型参数与类的泛型参数没有任何关系
System.out.println("#1 generic method test");
List<Boolean> booleans = dc.transFromArrayToList(bls);
for (Boolean b : booleans) {
System.out.println(b);
}
System.out.println("#2 static generic method test");
List<Boolean> bls1 = Computer.statictransFromArrayToList(bls);
for (Boolean b : bls1) {
System.out.println(b);
}
}
}