Java泛型总结(1)

含义:

  • 泛型(Generic type)是Java 语言中一种支持创建按类型进行参数化的类。
// 使用泛型之前
Map map = new HashMap();
map.put("key", "value");
String s = (String) map.get("key");
  • 上述代码中,Map.get() 的返回值类型为Object,所以需要强制类型转换。但是这就要求码农们人为的确保类型转换的正确性,否则会出现ClassCastException
  • 如果希望在代码编译检查阶段,能够自动发现上述可能存在的错误,并且不用人为地去进行强制类型转换的话,就要用到泛型了。

好处:

  • 泛型的主要目的是提高 Java 程序的类型安全。
  • 泛型允许编译器检查类型错误。类型错误会在编译时被捕获,而不会在运行时报 ClassCastException的错误。将类型检查从运行时改为编译时有助于找到程序的错误,提高程序的可靠性。

  • 比较下面两个例子

// 不使用泛型:
List list = new ArrayList();
list.put(new Integer(5));
Integer i = (Integer) list.get(0);

// 使用泛型:
List<Integer> list = new ArrayList<Integer>();
// Java1.7以上可以写为:
// List<Integer> list = new ArrayList<~>();
list.put(new Integer(5));
Integer i = list.get(0);
  • JDK 5.0 中集合框架中的 Map 接口:
public interface Map<K, V> {
    public void put(K key, V value);
    public V get(K key);
    ...
}
  • 其中的类型参数 K和V可以看成是指定类型的占位符,取决于我们申明变量时传递的参数类型。如下:
Map<String, String> map = new HashMap<String, String>();
map.put("key", "value");
// 使用泛型时,不需强制类型转换,因为编译器知道get()方法将返回一个String类型的值。 
String s = map.get("key");

向后兼容:

  • 从 JDK 5.0 开始,标准类库中的许多类,比如集合框架,都泛型化了。但是对于 JDK 5.0 之前版本,其代码不用修改就可以运行于5中,只是这样就得不到泛型的好处了。

  • 正是为了保证向后兼容,所以Java的泛型并不是真泛型,而是伪泛型。这是与C sharp的一个重要区别。


类型参数命名:推荐使用单个大写字母)

  • K => 键
  • V => 值
  • E => 异常类
  • T => 泛型

泛型不是协变的:

  • Object类是String类的父类,但是List<Object> 类不是 List<String>类的父类
// 有效代码
Integer[] intArray = new Integer[10];
Number[] numberArray = intArray;
// IntegerNumber的子类,所以一个Integer数组可以是一个Number数组

// 无效代码
List<Integer> intList = new ArrayList<Integer>();
List<Number> numberList = intList; // 报错
// 假如上述代码是成立的,那么下面这句代码就无法解释了
numberList.add(new Double(3.1415926));

类型通配符:

  • 假设有这样一个方法:
void dosthList(List l) {
    for (Object o : l) {
        ...
    }
}

如果试图用将一个List参数传递进去,会出现警告:破坏使用泛型的类型安全。

  • 如果将该方法改写为如下所示:
void dosthList(List<Object> l) {
    for (Object o : l) {
        ...
    }   
}

仍然不会通过编译,因为对于泛型不存在协变,一个List<Integer>不是 一个List<Object>

  • 使用类型通配符:
void dosthList(List<?> l) {
    for (Object o : l) {
        ...
    }
}

上面代码中的问号是一个类型通配符。List<?> 是任何 List泛型的父类型,所以可以将 List<Object>List<Integer> 传递给该方法。


有限制类型:

  • 有时我们需要对类型参数指定约束,例如有一个类Jiarenyf类,使用类型参数 V,我们希望该参数由Number类来限制,即:
public class Jiarenyf<V extends Number> { ... }
  • 此时编译器允许创建 Jiarenyf<Integer>Jiarenyf<Float> 类型的变量,但会出现错误如果定义了Jiarenyf<String>类型的变量。也即,类型V必须为Number类的子类。在没有类型限制时,类型参数为Object类的子类。所以在List<?> 调用get()方法时返回Object类型的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值