泛型

  Java泛型是将类型由原来的具体的类型参数化,然后在使用时传入具体的类型。编译器在编译时会去掉类、接口或方法中类型参数的定义,目的是使得用了泛型的Java应用程序能够与未用泛型时创建的类库和应用程序保持兼容性。因此,需要知道类型才能执行的运算,如new运算、instanceof运算等,都无法执行。

定义泛型类型

  定义泛型类型时用“< >”包含一个类型参数,类型参数常用单个的大写字母表示,常用的有:

  T -> 类型

  E -> 元素

  K -> 关键字

  根据泛型定义位置的不同,可以分为:

泛型类

  泛型类是将类型参数定义在类名后:

1 class A<T> {
2 
3     public void test(T t) {
4         System.out.println(t);
5     }
6 
7 }
A

  继承泛型类的类可以不指定泛型类型:

1 class B<T> extends A<T> {
2 
3     @Override
4     public void test(T t) {
5         super.test(t);
6     }
7 
8 }
B

  也可以指定泛型类型:

1 class C extends A<String> {
2 
3     @Override
4     public void test(String s) {
5         super.test(s);
6     }
7 
8 }
C

  创建泛型类实例时指定泛型类型:

 1 @Test
 2 void testGenericsClass() {
 3     // 指定泛型类型为java.lang.Integer
 4     B<Integer> b = new B<Integer>();
 5     b.test(1);
 6 //    b.test("1");   // 报错,传入参数只能为Integer类型
 7 
 8     // 定义类时已经指定泛型类型为java.lang.String
 9     C c = new C();
10     c.test("1");
11 }
testGenericsClass

  输出结果:

  

泛型接口

  泛型接口是将类型参数定义在接口名后。与泛型类相似,实现泛型接口的类可以指定或不指定泛型类型。

泛型方法

  泛型方法时将类型参数定义在返回值类型前。

1 class D {
2 
3     public<T> void test(T t) {
4         System.out.println(t);
5     }
6 
7 }
D

  调用同一个对象的泛型方法可以传入不同的泛型类型。这是泛型方法比泛型类实用的一点。

  调用泛型方法可以在方法名前加上泛型类型。如果泛型方法参数中使用了泛型,则可以省略前面指定的泛型类型,编译器会根据参数类型自动匹配。

1 @Test
2 void testGenericsMethod() {
3     D d = new D();
4     // 指定泛型类型为java.lang.String,传入的参数只能为String类型
5     d.<String>test("1");
6     // 不指定泛型类型,编译器根据参数“1”自动识别泛型类型为java.lang.Integer
7     d.test(1);
8 }
testGenericsMethod

  输出结果:

  

限界类型参数

  限界类型参数是限定可以取代类型参数的实际类型的范围,格式为:<类型参数 extends 类>,表示传入的泛型类型必须为extends指定的类或其子类。

1 class E<T extends Number> {
2 
3     public void test(T t) {
4         System.out.println(t);
5     }
6 
7 }
E
1 @Test
2 void testGenericsBoundedTypeParameter() {
3     E<Integer> e = new E<Integer>();
4 //    E<String> e = new E<String>();   // 报错,java.lang.String类不是java.lang.Number类的子类
5 }
testGenericsBoundedTypeParameter

通配符

  泛型的通配符用“?”表示,代表未知类型,分为三种:

  无界通配符(<?>):代表任意类型。

  限界通配符(<? extends T>):代表T类或T的某个子类。

  下界通配符(<? super T>):代表T类或T的某个父类。

 1 @Test
 2 void testGenericsWildcard() {
 3     // 无界通配符
 4     A<?> a1;
 5     a1 = new A<Integer>();
 6     a1 = new A<String>();
 7 
 8     // 限界通配符
 9     A<? extends Number> a2;
10     a2 = new A<Integer>();
11 //    a2 = new A<String>();   // 报错,java.lang.String类不是java.lang.Number类的子类
12 
13     // 下界通配符
14     A<? super Integer> a3;
15     a3 = new A<Number>();
16 //    a3 = new A<String>();   // 报错,java.lang.String类不是java.lang.Integer类的父类
17 }
testGenericsWildcard

posted on 2019-06-14 17:24  寇德·坡特  阅读(155)  评论(0编辑  收藏  举报

导航