【摘要】Java泛型~
前言
在JDK5.0之前,没有泛型,那时的集合类本质上是以Object为泛型,因为这样可以存放任意对象。
如:
1 2 3 4 5 6
| List a = new ArrayList(); a.add(123); a.add("jack"); a.add(new Book(...));
|
可见,在没有泛型的年代,集合在使用时,程序员要“主动”遵守约定,就是一个集合只存放一种类型。
现在,JDK5.0开始,引入了泛型,它的目的就是让这些“容器”类能够事先约定好它将要存放什么类型的数据。并且JVM负责检查。
如:
1 2 3
| List<String> b = new ArrayList<>(); b.add(123); b.add("jack");
|
泛型 [Generic Type]
所谓泛型,就是 类型参数化[type parameterize]。也就是把类型当参传一样的传递。
它的语法:
在JDK5.0中,整个JCF都全部采用泛型的语法重写过。
如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class ArrayList { public boolean add(Object e) { ... } }
public class ArrayList<E> { public boolean add(E e) { } }
List<Book> bList = new ArrayList<>(); List<Integer> iList = new ArrayList<>(); Map<String,Book> map = new HashMap<>();
Set<Entry<Integer,Book>> set = ...;
|
思考?是不是所有类型都要定义成泛型类?
当然不是,如:
1 2 3 4 5 6
| public class Student { private Integer id; private String name; private int age; }
|
只有需要把类型当做参数传递的类型定义时才需要泛型。
如何使用泛型类?
如何自定义泛型类?
如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class Entry { private Object key; private Object value; public Object getKey() { return this.key; } public void setValue(Object obj) { this.value = obj; } }
Entry e1 = new Entry(123,"Spring"); Entry e2 = new Entry("Jack",18L);
public class Entry<K, V> { private K key; private V value; public K getKey() { return this.key; } public void setValue(V obj) { this.value = obj; } }
Entry<Integer,String> e1 = new Entry<>(123,"Spring"); Entry<String, Long> e2 = new Entry<>("Jack",18L);
|
泛型仅仅是编译期间的概念,在运行时是没有泛型的。泛型是不存在多态性的。
如:
1 2 3 4
| Number n = new Integer(100); List b = new ArrayList();
List<Number> bn = new ArrayList<Integer>();
|
注:泛型是不存在多态性的
所以,上面这条语句是错误的。
1
| List<Number> bn = new ArrayList<>();
|
再看:
1 2 3 4
| List<Number> bn1 = new ArrayList<>(); List<Integer> bn2 = new ArrayList<>();
bn1 = bn2;
|
泛型的通配符
? 可以通配任意类型
? extends 类型 来限定通配[?所代表的类型比后面的类型要小或一样]
? super 类型 来限定通配[?所代表的类型比后面的类型要大或一样]
如:
1 2 3 4 5 6 7 8
| List<?> a = new ArrayList<Integer>();
a.add(null); a.dd(100);
List<Long> b = new ArrayList<>();
a = b;
|
自定义泛型方法
就是指所在的类本身不是泛型类,而这个类的方法要定义成泛型方法。
语法:
1 2 3
| 修饰符 <T> 返回类型 方法名(参数列表) throws 异常 { //方法体 }
|
在 修饰符 和 返回类型之间,使用 定义好泛型字母,然后,在方法的参数或方法体中就可以使用这个泛型字母。
如:
1 2 3 4 5 6
| public class Demo { public static <T> void ma(T o) { } }
|
例:定义一个泛型方法,找到两个对象的中的最大值。
1 2 3 4 5
| public class Demo { public static <T extends Comparable<T>> T max(T a, T b) { } }
|
结束语
bye~