在集合中为甚麽建议使用泛型.之前在Java SE5之前的容器的一个主要问题时编译器允许你向容器中插入不正确的类型
package com.tmx.On_4_March;
import java.util.ArrayList;
class Apple {
private static long counter;
private final long id = counter++;
public long id() {
return id;
}
}
class Orange {
}
public class Exp11_1 {
public static void main(String[] args) {
fun1();
fun3();
}
/**
* 不加泛型,ArrayList保存的是object,所以你可以添加Apple和Orange对象
* 但当从ArrayList中获取对象时,得到的只是Object的引用,而不是具体某类对象
* 所以必须的强制转型
*/
public static void fun1() {
ArrayList apples=new ArrayList();
for (int i = 0; i < 3; i++) {
apples.add(new Apple());
}
apples.add(new Orange());
for(int i=0;i<apples.size();i++) {
if(apples.get(i) instanceof Apple) {
System.out.println(((Apple)apples.get(i)).id());
}else {
continue;
}
}
}
/**
* 加了泛型,只能保存同类型对象.
* 泛型可以在编译期防止将错误的类型对象放置到容器中
* 在从list中取出元素时,类型转换也不是必须的了,因为list知道它保存的是甚麽类型,因此它会在调用
* get时替你执行转型.
* 故使用泛型,不仅知道编译器将会检查你放置到容器中的对象类型,而且在使用容器中的对象时,可以使用更加清晰的语法
*/
public static void fun2() {
ArrayList<Apple> apples=new ArrayList<Apple>();
for (int i = 0; i < 3; i++) {
apples.add(new Apple());
}
//apples.add(new Orange()); 编译期错误
for (Apple apple : apples) {
apple.id();
}
for (int i=0;i<apples.size();i++) {
apples.get(i).id();
}
}
/**
* 泛型不仅限于只能将该确切类型的对象放置到容器里,向上转型也可以像作用于其他类型一样作用于泛型
*/
public static void fun3() {
ArrayList<Apple> list=new ArrayList<Apple>();
list.add(new Apple());
list.add(new FruitA());
list.add(new FruitB());
list.add(new FruitC());
for (Apple apple : list) {
System.out.println(apple);
}
}
}
class FruitA extends Apple{}
class FruitB extends Apple{}
class FruitC extends FruitB{}
上述代码的执行结果
Apple对象数量:0
Apple对象数量:1
Apple对象数量:2
com.tmx.On_4_March.Apple@70dea4e
com.tmx.On_4_March.FruitA@5c647e05
com.tmx.On_4_March.FruitB@33909752
com.tmx.On_4_March.FruitC@55f96302
fun3是通过Object的toString()方法产生的,该方法打印类名,后面跟随该对象的散列码的无符号16进制表示(这个散列码是通过hashCode()方法产生的)