泛型是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。
泛型的格式:
<数据类型>
注意:此处的数据类型这能是引用类型
好处:
A:把运行时期的问题提前到了编译期间
B:避免了强制类型转换
C:优化了程序设计
import java.util.ArrayList;
public class ArrayListDemo { public static void main(String[] args) { ArrayList array = new ArrayList(); array.add("hello"); array.add("world"); array.add("java");for (int x = 0; x < array.size(); x++) { String s = (String) array.get(x);//由于没有使用泛型所以要进行强制类型转换 System.out.println(s); } } }
那么泛型在什么地方要使用呢?
我们可以查看API,如果类、接口和抽象类的后面跟有<E>就说明要使用泛型,一般来说就是在集合中使用。
泛型的由来:
在早期的时候我们可以使用Object类型来接收任意的对象类型,但是在实际的使用过程中,向上转型是没有任何问题的,但是在向下转型的时候其实隐含了类型转换的问题,会有强制类型转换的问题,也就存在着隐患,所以Java在JDK5以后就提供了泛型来解决这个安全问题,提高程序的安全性。
泛型的应用:
A:泛型类
就是把泛型定义在类上
格式:public class 类名<泛型类型 1,...>
注意:泛型的类型必须是引用类型
//定义一个泛型类 class ObjectTool<T> { private T obj; public T getObj() { return obj; } public void setObj(T obj) { this.obj = obj; } } //定义一个测试类 public class ObjectToolDemo { public static void main(String[] args) { ObjectTool<String> ot = new ObjectTool<String>(); // ot.setObj(new Integer(27)); //这个时候编译期间就过不去 ot.setObj(new String("林青霞")); String s = ot.getObj(); System.out.println("姓名是:" + s); ObjectTool<Integer> ot2 = new ObjectTool<Integer>(); // ot2.setObj(new String("风清扬"));//这个时候编译期间就过不去 ot2.setObj(new Integer(27)); Integer i = ot2.getObj(); System.out.println("年龄是:" + i); } }
B:泛型方法
就是把泛型定义在了方法上
格式:public<泛型类型> 返回类型 方法名(泛型类型)
好处:方法可以接收任意类型的数据
public class ObjectTool { //定义一个泛型方法 public <T> void show(T t) { System.out.println(t); } } //定义一个测试类 public class ObjectToolDemo { public static void main(String[] args) { // 定义泛型方法后 ObjectTool ot = new ObjectTool(); ot.show("hello"); ot.show(100); ot.show(true); } }
C:泛型接口
就是把泛型定义在接口上
格式:public interface 接口名<泛型类型1...>
泛型接口的实现类在实现接口的时候分以下两种情况
第一种情况:实现该接口的时候已经知道是什么类型
//定义一个泛型接口 interface Inter<T> { public abstract void show(T t); } //泛型类的实现类在实现接口是知道是什么类型的了 public class InterImpl implements Inter<String> { @Override public void show(String t) { System.out.println(t); } } //测试类 public class InterDemo { public static void main(String[] args) { Inter<String> i = new InterImpl(); i.show("hello"); } }
第二种情况:实现该接口的时候还不知道是什么类型
//定义一个泛型类 public interface Inter<T> { public abstract void show(T t); } //实现该接口的时候还不知道是什么类型的 public class InterImpl<T> implements Inter<T> { @Override public void show(T t) { System.out.println(t); } } //测试类 public class InterDemo { public static void main(String[] args) { Inter<String> i = new InterImpl<String>(); i.show("hello"); Inter<Integer> ii = new InterImpl<Integer>(); ii.show(100); } }
泛型高级(通配符)
泛型通配符<?>
表示任意类型,如果没有明确,那么就是Object以及任意的Java类了
? extends E
向下限定,E及其子类
? super E
向上限定,E及其父类
public class GenericDemo { public static void main(String[] args) { // 泛型如果明确的写的时候,前后必须一致 Collection<Object> c1 = new ArrayList<Object>(); // Collection<Object> c2 = new ArrayList<Animal>();//报错 // Collection<Object> c3 = new ArrayList<Dog>();//报错 // Collection<Object> c4 = new ArrayList<Cat>();//报错 // ?表示任意的类型都是可以的 Collection<?> c5 = new ArrayList<Object>(); Collection<?> c6 = new ArrayList<Animal>(); Collection<?> c7 = new ArrayList<Dog>(); Collection<?> c8 = new ArrayList<Cat>(); // ? extends E:向下限定,E及其子类 // Collection<? extends Animal> c9 = new ArrayList<Object>();//报错 Collection<? extends Animal> c10 = new ArrayList<Animal>(); Collection<? extends Animal> c11 = new ArrayList<Dog>(); Collection<? extends Animal> c12 = new ArrayList<Cat>(); // ? super E:向上限定,E极其父类 Collection<? super Animal> c13 = new ArrayList<Object>(); Collection<? super Animal> c14 = new ArrayList<Animal>(); // Collection<? super Animal> c15 = new ArrayList<Dog>();//报错 // Collection<? super Animal> c16 = new ArrayList<Cat>();//报错 } } class Animal { } class Dog extends Animal { } class Cat extends Animal { }