Java 5 添加了泛型,提供了编译时类型安全检测机制,该机制容许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,能够为之前处理通用对象的类和方法,指定具体的对象类型。听起来有点抽象,因此咱们将立刻看一些泛型用在集合上的例子:javascript
先看一个没有泛型的集合例子:html
List list = new ArrayList(); list.add(new Integer(2)); list.add("a String");
由于 List 能够添加任何对象,因此从 List 中取出的对象时,由于不肯定(List不记住元素类型)当时候保存进 List 的元素类型,这个对象的类型只能是 Object ,还必须由程序编写者记住添加元素类型,而后取出时再进行强制类型转换就,以下:java
Integer integer = (Integer) list.get(0); String string = (String) list.get(1);
一般,咱们只使用带有单一类型元素的集合,而且不但愿其余类型的对象被添加到集合中,例如,只有 Integer 的 List ,不但愿将 String 对象放进集合,而且也不想本身记住元素类型,而且强制类型转换还可能会出现错误。程序员
使用 Generics(泛型)就能够设置集合的类型,以限制能够将哪一种对象插入集合中。 这能够确保集合中的元素,都是同一种已知类型的,所以取出数据的时候就没必要进行强制类型转换了,下面是一个 String 类型的 List 的使用例子:数组
List<String> strings = new ArrayList<String>(); strings.add("a String"); String aString = strings.get(0);
以上这个 List
Java 泛型从 Java 7 开始,编译器能够自动类型判断,能够省略构造器中的泛型,下面是一个Java 7 泛型例子:markdown
List<String> strings = new ArrayList<>();
这也叫作菱形语法(<>), 在上面的示例中,实例化 ArrayList 的时候,编译器根据前面 List
foreach 循环能够很好地与泛型集合整合,以下:async
List<String> strings = new ArrayList<>(); // 这里省略将 String 元素添加进集合的代码... for(String aString : strings){ System.out.println(aString); }
也可使用泛型迭代器遍历集合,以下:ide
List<String> list = new ArrayList<String>; Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String aString = iterator.next(); }
注意,泛型类型检查仅在编译时存在。在运行时,可使用反射或者其余方式使字符串集合插入其余对象,但通常不会这样作。
固然泛型的用处不只仅限于集合。
从上面的内容中,咱们已了解泛型的大概理念。
能够在自定义 Java 类上使用泛型,并不局限于 Java API 中的预约义类。定义泛型类只须要在类名后紧跟
public class GenericFactory<T> { Class theClass = null; public GenericFactory(Class theClass) { this.theClass = theClass; } public T createInstance() throws Exception { return (T) this.theClass.newInstance(); } }
其中 Class.newInstance() 方法是反射知识的内容,这里只要知道此方法用于 theClass 类对象的建立就行。
GenericFactory<MyClass> factory = new GenericFactory<MyClass>(MyClass.class); MyClass myClassInstance = factory.createInstance(); GenericFactory<SomeObject> factory1 = new GenericFactory<SomeObject>(SomeObject.class); SomeObject someObjectInstance = factory1.createInstance();
使用泛型,咱们就没必要转换从 factory.createInstance() 方法返回的对象,会自动返回 new GenericFactory
一个泛型方法定义以下:
public static <T> T addAndReturn(T element, Collection<T> collection){ collection.add(element); return element; }
其中 T 是方法返回值,
public T createInstance() throws Exception { ... }
这不是一个泛型方法,而是 GenericFactory
注意在泛型方法中,参数有 2 个,第一个是 T 类型的参数,第二个是元素类型为 T 的 Collection 集合,编译器会根据实际参数来推断 T 为什么种类型 ,以下这样是彻底可行的:
String stringElement = "stringElement"; List<Object> objectList = new ArrayList<Object>(); Object theElement = addAndReturn(stringElement, objectList);
如上,第一个参数为 String 类型,第二个是 List