简述java泛型的11个知识点,文末有之前看到一篇通俗易懂的泛型讲解资料。
泛型Generics实现了参数化类型的概念,也就是支持多重类型。Java中泛型的实现事实上不是很广泛,甚至让人疑问这个特性是否符合“Generics”这个称谓。Java的泛型可能无法完全做到你期望的所有事情。但是不代表java的泛型是没用的。本文会讲解java中泛型的强大之处和限制,使得我们能更高效地使用该特性。
1、tuple:多元组
将一组对象包装到一个对象中。用于一些methods需要返回多个对象的时候。
当需要两个对象的tuple(final用于提高安全性):
public class TwoPurple<A, B> {
public final A first;
public final B second;
public TwoPurple(A first, B second) {
this.first = first;
this.second = second;
}
public String toString() {
return first+":"+second;
}
}
当你需要三个或者更多对象的tuple时,通过继承进行扩展。
public class ThreeTuple<A, B, C> extends TwoPurple<A, B>{
public final C three;
public ThreeTuple(A first, B second, C three) {
super(first, second);
this.three = three;
}
public String toString() {
return ""+first+":"+second+":"+three;
}
}
通过泛型,可以轻松创建任何types组的tuple用于返回。
2、泛型可以用于stack、list等数据结构,用于存储各种不同类型的数据。
3、泛型接口
public interface Generator<T> {
T next();
}
泛型接口与泛型类的用法很相似。
4、泛型方法
public <T> void genericMethod(T a) {
System.out.println("Im a generic method"+a);
}
泛型方法需要将泛型参数列表,放置于返回值前(如上图)
1. 泛型类需要在实例化时指定参数的类型
2. 泛型方法不需要指明,编译器会自动识别。
5、可变参数varargs和泛型方法
//单纯可变参数
public static ArrayList makeList(int... args) {
ArrayList list = new ArrayList();
for(int num:args) {
list.add(num);
}
return list;
}
//可变参数和泛型完美配合
public static <T> ArrayList<T> makeList(T... args) {
ArrayList<T> list = new ArrayList<>();
for(T arg: args) {
list.add(arg);
}
return list;
}
这个makeList方法和 java.util.Arrays.asList( ) 的标准库方法功能室一样的。
6、泛型的应用
- 通用的generator 2.set
7、泛型的bounds
对泛型使用的参数类型进行了限制。
interface MyColor...
class Colored<T extends MyColor> {
....
}
//有接口MyColor,T必须要继承自MyColor
class Dimension...
//有接口Dimension,T的限制不能先inerface后class!
class ColoredDimension<T extends HasColor & Dimension> {...}
//下面先class后interface才是正确的
class ColoredDimension<T extends Dimension & HasColor>{...}
//-----------
//如果类需要制定bound的泛型,此外还要继承superclass如下即可
class Colored2<T extends HasColor> extends HoldItem<T>{...}
8、泛型方法的限制
泛型方法添加bound,需要在这个泛型列表中表示。如下:
public <T extends Number> T showKeyName(Generic<T> container){...}
9、泛型通配符
有一个泛型类Generic,比如Number是Integer的超类,有实参Generic obj1和Genericobj2,对于需要Generic参数的地方,却无法使用Generic,因为两者已经不是父子类关系。这是后将形参变成Generic<?> obj,就是能传入两者的。因为?可以是所有类型的超类。
10、静态方法与泛型
如果静态方法要使用泛型,则必须将静态方法变成泛型方法。
11、泛型数组
Java终不能创建一个确切的泛型类型的数组
List<String>[] ls = new ArrayList<String>[10]; × 不可以
List<?>[] ls = new ArrayList<?>[10]; √ 可以
List<String>[] ls = new ArrayList[10]; √ 可以
对于通配符的模式,从数组中取出的值需要进行类型转换。
List<?>[] lsa = new List<?>[10]; //通配符形式
List<Integer> li = new ArrayList<Integer>();
li.add(new Integer(3));
Integer i = (Integer) lsa[1].get(0); // 进行类型转换后使用
12、Java泛型学习链接
http://blog.csdn.net/s10461/article/details/53941091