java 泛型
1.java中为什么要有泛型呢?
为解决数据类型安全性问题,保证程序在编译时没有发出警告,运行时就不会产生ClassCastException异常。其主要原理时在类声明时通过一个标识表示类中的某个属性的或者是某个方法的返回值及参数类型。
2.
java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型相关信息擦去,并在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说反省信息不会进入运行时阶段。
3.泛型的使用:主要有三种 泛型类 , 泛型方法 , 泛型接口
4.泛型类:
public static void main(String[] args) { //A<String> a = new A<Integer>();//此时会报错,前后泛型必须保持一致 A<String> a = new A<String>();//在new A的对象指定泛型的类型String a.setKey("aaaa");//对象使用setKey(T key)方法,调用的形参就是String类型的 String a1= a.getKey();//T getKey()返回值也为String A<Integer> a2 = new A<Integer>(); a2.setKey(1); int a3 = a2.getKey(); A a4 = new A();//不指定泛型则默认是Object型 a4.setKey("2"); Object obj = a4.getKey();// //a = a2;//同一类的对象,指定了不同的泛型不能相互赋值 } } //此时泛型T可以任意取名,,一般使用T,意为Type class A<T>{ private T key; public void setKey(T key) { this.key = key; } public T getKey() { return this.key; }
5.泛型方法:
public static void main(String[] args) { B1<String> b = new B1<String>(); B1<Integer> b1 = new B1<Integer>(); B2 b2 = new B2(); } } interface IB<T>{ T test(T t); } //未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需要将泛型声明一起加到类中 class B1<T> implements IB<T>{ @Override public T test(T t) { // TODO Auto-generated method stub return t; } } //如果实现接口是指定泛型的具体数据类型,这个类实现接口的所有方法的位置都要将泛型替换为实际的数据类型 class B2 implements IB<String>{ @Override public String test(String t) { // TODO Auto-generated method stub return null; }
6.泛型接口:
public static void main(String[] args) { //泛型方法在调用之前没有固定类型,在调用时传入的参数是什么类型,就会把泛型改为什么类型 // Cc<Object> c = new Cc<Object>(); c.Test("sss"); int i = c.Test1(2);//传递的参数时Integer就会把泛型改为Integer,返回值就为Integer } } class Cc<E>{ private E e; //静态方法中的泛型 public static <T> void Test3(T t) { //在静态方法中不能使用类中定义的泛型 //System.out.println(this.e);//报错 System.out.println(t); } //无返回值的泛型方法 public <T> void Test(T s) { T t = s; } //有返回值的泛型方法 public <T> T Test1(T s) { //在类上定义的泛型可以在普通方法中使用 System.out.println(this.e); return s; } //形参为可变参数的泛型方法 public <T> void Test2(T...strs) { for(T s: strs) { System.out.println(s); } }
7.泛型通配符 ? :
不确定集合中元素的具体类型使用?替代:
具体应用如下:
public class Test12 { public static void main(String[] args) { Dd d = new Dd(); List<String> list = new ArrayList<String>(); d.test(list); List<Integer> list1 = new ArrayList<Integer>(); d.test(list1); List<C1> lc = new ArrayList<C1>(); d.test1(lc); List<A1> la = new ArrayList<A1>(); //d.test1(la);//报错 } } class Dd{ public void test(List<?> list) {//test方法需要一个list集合作为参数,但是不确定集合的类型 } public void test1(List<? extends C1> list) { } } class A1{ } class B1 extends A1{ } class C1 extends B1{ } class D1 extends C1{ }