• 泛型


      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
  • 相关阅读:
    freemarker 遍历 hashmap 到select option
    三分钟跑起jsblocks
    hibernate_@GeneratedValue
    跑github上的Symfony项目遇到的问题2
    Activiti使用过程_1
    Symfony官方视频教程
    跑github上的Symfony项目遇到的问题
    剧本杀
    随遇而安
    开发者职场心得
  • 原文地址:https://www.cnblogs.com/lqkStudy/p/11022430.html
Copyright © 2020-2023  润新知