Java基础学习笔记4——泛型

  1. 泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

  2. 一些常用的泛型类型变量:

    • E:元素(Element),多用于java集合框架
    • K:关键字(Key)
    • N:数字(Number)
    • T:类型(Type)
    • V:值(Value)
    • K,V:代表Map的键值对(Key,Value)
  3. 泛型类定义的语法为:

    [访问修饰符] class 类名称 <T>
    

    示例如下:

    public class GenericClass<T> {
        private T data;
        
        // 泛型不能使用在静态属性上
        //private static T javaee;
    
        public T getData() {
            return data;
        }
    
        public void setData(T data) {
            this.data = data;
        }
    
        public static void main(String[] args) {
            GenericClass<String> genericClass=new GenericClass<>();
            genericClass.setData("Generic Class");
            System.out.println(genericClass.getData());
        }
    }
    
  4. 泛型接口的使用示例如下:

    public interface GenericIntercace<T> {
        //接口中泛型字母不能使用在全局常量中
        //public static final T MAX_VALUE = 100;
        //T MAX_VALUE;
        
         T getData();
    }
    

    实现泛型接口方式一:

    public class ImplGenericInterface1<T> implements GenericIntercace<T> {
        private T data;
    
        private void setData(T data) {
            this.data = data;
        }
    
        @Override
        public T getData() {
            return data;
        }
    
        public static void main(String[] args) {
            ImplGenericInterface1<String> implGenericInterface1 = new ImplGenericInterface1<>();
            implGenericInterface1.setData("Generic Interface1");
            System.out.println(implGenericInterface1.getData());
        }
    }
    

    实现泛型接口方式二:

    public class ImplGenericInterface2 implements GenericIntercace<String> {
        @Override
        public String getData() {
            return "Generic Interface2";
        }
    
        public static void main(String[] args) {
            ImplGenericInterface2 implGenericInterface2 = new ImplGenericInterface2();
            System.out.println(implGenericInterface2.getData());
        }
    }
    
  5. 泛型方法定义的语法为:

    [访问修饰符] [static] <T> 返回值类型 方法名(T 参数列表)
    

    使用示例如下:

    public class Method {
     
      // 泛型方法,在返回类型前面使用泛型字母
      public static <T> void test1(T t){
        System.out.println(t);
      }
      
      // T 只能是list 或者list 的子类
      public static <T extends List> void test2(T t){
        t.add("aa");
      }
      
      // T... 可变参数   --->   T[]
      public static <T extends Closeable> void test3(T...a) {
        for (T temp : a) {
         try {
           if (null != temp) {
             temp.close();
           }
         } catch (Exception e) {
           e.printStackTrace();
         }
        }
      }
      
      public static void main(String[] args) throws FileNotFoundException {
        test1("java 是门好语言");
        test3(new FileInputStream("a.txt"));
      }
    }
    
  6. 使用泛型方法时,至少返回值或参数有一个是泛型定义的,而且应该保持一致,否则可能会受到各种限制。

  7. 泛型适用于多种数据类型执行相同的代码(代码复用)

  8. 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)

  9. 限定泛型类型变量

    • 对类的限定:

      public class TypeLimitForClass<T extends List & Serializable> {
          private T data;
      
          public T getData() {
              return data;
          }
      
          public void setData(T data) {
              this.data = data;
          }
          
      }
      
    • 对方法的限定:

      /**
       * 限定类型使用extends关键字指定
       * 可以使用类、接口,类放在前面接口放在后面用&符号分割
       * 例如:<T extends ArrayList & Comparable<T> & Serializable>
       */
      public static <T extends Comparable<T>> T getMin(T a, T b) {
          return (a.compareTo(b) < 0) ? a : b;
      }
      
  10. 泛型中的约束和局限性

    • 泛型类只能用在成员变量上,只能使用引用类型,基本类型无法作为泛型类型。

      // 基本类型无法作为泛型类型
      // GenericRestrict1<int> genericRestrictInt = new GenericRestrict1<>();
      
    • 泛型接口只能用在抽象方法上。

    • 不能实例化泛型类。

      /**
       * 不能实例化泛型类
       * Type parameter 'T' cannot be instantiated directly
       */
      public void setData() {
      	//this.data = new T();
      }
      
    • 静态变量或方法不能引用泛型类型变量,但是静态泛型方法是可以的。

      /**
       * 静态变量或方法不能引用泛型类型变量
       * 'com.jay.java.泛型.restrict.GenericRestrict1.this' cannot be referenced from a static context
       */
      // private static T result;
      
      // private static T getResult() {
      //		return result;
      // }
      
      /**
       * 静态泛型方法是可以的
       */
      private static <K> K getKey(K k) {
          return k;
      }
      
    • 无法使用instanceof关键字或==判断泛型类的类型。

      GenericRestrict1<Integer> genericRestrictInteger = new GenericRestrict1<>();
      GenericRestrict1<String> genericRestrictString = new GenericRestrict1<>();
      
      /**
       * 无法使用instanceof关键字判断泛型类的类型
       * Illegal generic type for instanceof
       */
      // if(genericRestrictInteger instanceof GenericRestrict1<Integer>){
      // 		return;
      // }
      
      /**
       * 无法使用“==”判断两个泛型类的实例
       * Operator '==' cannot be applied to this two instance
       */
      // if (genericRestrictInteger == genericRestrictString) {
      // 		return;
      // }
      
    • 泛型类的原生类型与所传递的泛型无关,无论传递什么类型,原生类是一样的。

      // 泛型类的原生类型与所传递的泛型无关,无论传递什么类型,原生类是一样的
      System.out.println(normalClassA == normalClassB);//false
      System.out.println(genericRestrictInteger == genericRestrictInteger);//
      System.out.println(genericRestrictInteger.getClass() == genericRestrictString.getClass()); //true
      System.out.println(genericRestrictInteger.getClass());//com.jay.java.泛型.restrict.GenericRestrict1
      System.out.println(genericRestrictString.getClass());//com.jay.java.泛型.restrict.GenericRestrict1
      
    • 泛型数组可以声明但无法实例化。

      // 泛型数组可以声明但无法实例化
      GenericRestrict1<String>[] genericRestrict1s;
      // genericRestrict1s = new GenericRestrict1<String>[10];
      genericRestrict1s = new GenericRestrict1[10];
      genericRestrict1s[0]=genericRestrictString;
      
    • 泛型类不能继承Exception或者Throwable

      /**
       * 泛型类不能继承Exception或者Throwable
       * Generic class may not extend 'java.lang.Throwable'
       */
      // private class MyGenericException<T> extends Exception {
      // }
      //
      // private class MyGenericThrowable<T> extends Throwable {
      // }
      
    • 不能捕获泛型类型限定的异常,但可以将泛型限定的异常抛出。

      /**
       * 不能捕获泛型类型限定的异常
       * Cannot catch type parameters
       */
      public <T extends Exception> void getException(T t) {
          // try {
          //
          // } catch (T e) {
          //
          // }
      }
      
      /**
       *可以将泛型限定的异常抛出
       */
      public <T extends Throwable> void getException(T t) throws T {
          try {
      
          } catch (Exception e) {
              throw t;
          }
      }
      
  11. 泛型类型继承规则

    • 对于泛型参数是继承关系的泛型类之间时没有继承关系的。
    • 泛型类可以继承其它泛型类,例如:public class ArrayList<E> extends AbstractList<E>
    • 泛型类的继承关系在使用中同样会受到泛型类型的影响。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值