Java泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
一、先看下面的例子:
import java.util.*; public class MyDemo { public static void main(String[] args) { List arrayList = new ArrayList(); arrayList.add("hello"); arrayList.add(1688); for(int i = 0; i< arrayList.size();i++){ String item = (String)arrayList.get(i); System.out.println("当前值:" + item); } } }
上面代码编译可以通过,但执行时报错:
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at MyDemo.main(MyDemo.java:10)
二、对代码作如下修改,则会在编译阶段就会出错
import java.util.*; public class MyDemo { public static void main(String[] args) { List<String> arrayList = new ArrayList<String>(); arrayList.add("hello"); arrayList.add(1688); for(int i = 0; i< arrayList.size();i++){ String item = (String)arrayList.get(i); System.out.println("当前值:" + item); } } }
%:WorkhelloworldMyDemo.java:7: 错误: 对于add(int), 找不到合适的方法
arrayList.add(1688);
^
三、泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法
1. 泛型类示范代码
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型 //在实例化泛型类时,必须指定T的具体类型 class Generic<T>{ //key这个成员变量的类型为T,T的类型由外部指定 private T key; public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定 this.key = key; } public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定 return key; } } public class MyDemo { public static void main(String[] args) { //泛型的类型参数只能是类类型(包括自定义类),不能是简单类型 //传入的实参类型需与泛型的类型参数类型相同,即为Integer. Generic<Integer> genericInteger = new Generic<Integer>(123456); //传入的实参类型需与泛型的类型参数类型相同,即为String. Generic<String> genericString = new Generic<String>("key_vlaue"); System.out.println(genericInteger.getKey()); System.out.println(genericString.getKey()); } }
2. 泛型接口示范代码
import java.util.*; interface Generator<T> { public T next(); } class FruitGenerator implements Generator<String> { private String[] fruits = new String[]{"Apple", "Banana", "Other"}; @Override public String next() { Random rand = new Random(); return fruits[rand.nextInt(3)]; } } class CarGenerator implements Generator<Boolean> { private Boolean[] myCar = new Boolean[]{true, false, true, false}; @Override public Boolean next() { Random rand = new Random(); return myCar[rand.nextInt(3)]; } } public class MyDemo { public static void main(String[] args) { FruitGenerator fruit = new FruitGenerator(); System.out.println(fruit.next()); System.out.println(fruit.next()); System.out.println(fruit.next()); CarGenerator car = new CarGenerator(); System.out.println(car.next()); System.out.println(car.next()); System.out.println(car.next()); } }
3. 类中的泛型方法
public class GenericFruit { static class Fruit{ @Override public String toString() { return "fruit"; } } static class Apple extends Fruit{ @Override public String toString() { return "apple"; } } static class Person{ @Override public String toString() { return "Person"; } } static class GenerateTest<T>{ public void show_1(T t){ System.out.println(t.toString()); } // 在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型。 public <T> void show_2(T t){ System.out.println(t.toString()); } } public static void main(String[] args) { Apple apple = new Apple(); Person person = new Person(); GenerateTest<Fruit> generateTest = new GenerateTest<Fruit>(); //apple是Fruit的子类,所以这里编译正常 generateTest.show_1(apple); //下面一行代码编译器会报错,因为泛型类型实参指定的是Fruit,而传入的实参类是Person //generateTest.show_1(person); // 下面代码可以正常执行 generateTest.show_2(apple); generateTest.show_2(person); } }
文章参考:
https://blog.csdn.net/s10461/article/details/53941091