「笔记」Java 泛型

泛型定义

  • Java 1.5 新特性,本质就是参数化类型,即所操作的数据类型被指定为一个参数
  • 泛型的好处是在编译的时候进行类型安全检查,并且所有的强制转换都是自动和隐式的,以提高代码的重用率

主要规则

  • 只能是 类型,不能是基础简单类型(Integer / int )
  • 同一种泛型允许有多个实现实例,但实现实例之间互不兼容
  • 泛型的参数类型可以有多个
  • 泛型的参数类型可以使用extends、super语句,且可以使用通配符类型(?)

泛型类

  • 单参数泛型类

  • public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    {
    	......
    }
    
  • 多参数泛型类

  • public class HashMap<K,V> extends AbstractMap<K,V>
        implements Map<K,V>, Cloneable, Serializable {
        .....
        }
    

泛型接口

public interface List<E> extends Collection<E> {
	......
}

泛型方法

    public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
  • 在调用泛型方法时,若不指定泛型的情况下,泛型变量的类型为该方法中几种类型的同一父类的最小级,直到 Object
  • 初始化泛型类时,若不指定泛型,则默认取 Object

通配符(?)与 T 的区别

  • T:作用于模板上,用于将数据类型进行参数化,不能用于实例化对象
  • ?:在实例化对象的时候,不确定泛型参数的具体类型时,可以使用通配符进行对象定义

上界类型通配符(? extends)

List<? extends Number> list = new ArrayList<Integer>();
// 正确
Number numObject = list.get(0);
// 错误 Number无法直接赋予给 Integer(Java语法规范
Integer intObject = list.get(0);

// 错误 list无法确认实例化对象的具体类型(可能是 Integer、Long、Float等),add操作受限
list.add(new Integer(1)); 
  • 上界类型通配符 add 方法受限,但可以获取列表中的各种类型的数据,并赋值给父类型(extends Number)的引用

下界类型通配符(? super )

List<? super Integer> list = new ArrayList<Number>();
// 正确
list.add(new Integer(1));

// 错误 List<? super Integer> 无法确认 list 中存放的对象具体类型,get操作受限
Number numObj = list.get(0);
Integer intObj = list.get(0);
  • 下界类型通配符 get 方法受限,但可以往列表中添加各种数据类型的对象,同时限定通配符总是包括自己

原始类型

  • Java 总是会自动的为泛型类型提供一个相应的原始类型

    • 所谓原始类型就是是指泛型的第一个限定类型(从左向右)

    • public class ArrayList<E  extends Integer&Serializable> 
      {
      	......
      }
      
      • extends 后可以继承多个类、多个接口,原始类型为从左向右第一个类或接口(即这里的 Integer
      • 为了提高效率,应该将标签接口(即没有方法的接口)放在边界限定列表的末尾
    • 无限定类型泛型的原始类型默认为 Objec

    • public class ArrayList<E> 
      {
      	......
      }
      等价于
      public class ArrayList<E  extends Object> 
      {
      	......
      }
      

类型擦除

  • Java 中泛型的实现原理是类型擦除(type erasure)

  • 类型擦除是在编译器进行代码编译这个阶段进行的,在编译的时候泛型的类型参数会被原始类型(raw type)所替代

  • List<String> strList = new ArrayList<String>();
    List<Integer> intList = new ArrayList<Integer>();
    // true
    System.out.println(strList.getClass()==intList.getClass());
    
  • 更多详情:泛型的内部原理:类型擦除以及类型擦除带来的问题

学习资料来源:https://blog.csdn.net/claram/column/info/13746/4

发布了98 篇原创文章 · 获赞 197 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/YangDongChuan1995/article/details/91361265