Java 泛型和类型安全的容器
使用java SE5之前的容器的一个主要问题就是编译器允许你向容器插入不正确的类型,例如:
//: holding/ApplesAndOrangesWithoutGenerics.java // Simple container example (produces compiler warnings). // {ThrowsException} package object; import java.util.*; class Apple { private static long counter; private final long id = counter++; public long id() { return id; } } class Orange {} public class ApplesAndOrangesWithoutGenerics { @SuppressWarnings("unchecked")//@SuppressWanrings注解及其参数表示只有有关"不受检查的异常"的警告信息应该被抑制 //https://i.cnblogs.com/EditPosts.aspx?postid=9919361&update=1 public static void main(String[] args) { ArrayList apples = new ArrayList(); //一个apple容器 for(int i = 0; i < 3; i++) apples.add(new Apple()); // Not prevented from adding an Orange to apples: apples.add(new Orange()); //却可以插入一个Orange对象 for(int i = 0; i < apples.size(); i++) ((Apple)apples.get(i)).id(); //由于Orange 和Apple没有可以转型的关系,转型失败,运行错误 // Orange is detected only at run time } } /* (Execute to see output) *///:~
使用Java泛型创建类会非常复杂,但是,应用预定义的泛型通常会很简单,例如Apple的ArrayList可以声明为ArrayList<Apple>,而不仅仅时ArrayList,其中尖括号括起来的参数是类型参数(可以有多个),它指定了这个容器实例可以保存的类型,通过使用泛型,就可以在编译期防止错误类型的对象放置到容器中
//: holding/ApplesAndOrangesWithGenerics.java package object; import java.util.*; public class ApplesAndOrangesWithGenerics { public static void main(String[] args) { ArrayList<Apple> apples = new ArrayList<Apple>(); for(int i = 0; i < 3; i++) apples.add(new Apple()); // Compile-time error: // apples.add(new Orange());//编译器可以放置放置错误类型进apples中 for(int i = 0; i < apples.size(); i++) System.out.println(apples.get(i).id()); // Using foreach: for(Apple c : apples) System.out.println(c.id()); } } /* Output: 0 1 2 0 1 2 *///:~
当指定类某个类型作为泛型参数时,你不仅限于只能将该确切类型的对象放置到容器中,向上转型也可以像作用于其它类型一样作用于泛型
//: holding/GenericsAndUpcasting.java package object; import java.util.*; class GrannySmith extends Apple {} class Gala extends Apple {} class Fuji extends Apple {} class Braeburn extends Apple {} public class GenericsAndUpcasting { public static void main(String[] args) { ArrayList<Apple> apples = new ArrayList<Apple>(); apples.add(new GrannySmith()); apples.add(new Gala()); apples.add(new Fuji()); apples.add(new Braeburn()); for(Apple c : apples) System.out.println(c); } } /* Output: (Sample) GrannySmith@7d772e Gala@11b86e7 Fuji@35ce36 Braeburn@757aef *///:~