java的泛型
1.泛型的作用
防止随意的放置任何的对象,使用泛型后只能按我们使用时指定的类型添加以及会相应的进行编译时检查,在编译检查后会去除相应的泛型信息(在类型拭除后两个相同那么会认为是相同的,导致编译时错误,所以泛型在方法的重载的时候方法名需要不同),在类型转换的也会自动的相应的转换为相应的信息
//T extends GenenricyDemo1<T> 自限定 只能是自身或者子类
public class GenenricyDemo1<T extends GenenricyDemo1<T>> { public static <T> T test1(T t) { return t; } public <T> T test2(T t) { return t; } public T test3() { return null; } public static void main(String[] args) { String test1 = GenenricyDemo1.test1("a"); String test2 = new GenenricyDemo1<>().test2("b"); } }
public class GenericyDemo10 { //编译错误 // public void test1(Vector<String> vct){ // // } // public void test1(Vector<Object> vct){ // // } public void test1(Vector<String> vct) { } public void test2(Vector<Object> vct) { } }
2.泛型的编译时类型检查(泛型是没有多态。直接比较放入类的class文件,但是在数组中是可以有多态的)
public class GenericyDemo2 { public static void main(String[] args) { // ArrayList<Object> arrayList = new ArrayList<String>();//编译时错误,没有多态 ArrayList<String> arrayList = new ArrayList<>();//编译时正常 ArrayList arrayList1 = new ArrayList<String>();//编译时正常 ArrayList<Object> arrayList2=arrayList1 ;//编译时正常,编译时一行一行检查的 // arrayList2=arrayList;//编译时错误
//ArrayList<int> str=null;//编译错误,泛型参数只能对对象不能是基本类型的数据,不会自动包装
//? extends GenericyDemo9Fater是不能使用的(类 接口等)
//if(arg instanceof T) {} // 编译时错误
//T var = new T(); //编译时错误,不能实例化 } }
3.继承实现
@SuppressWarnings("all") public class GenericyDemo3<B, A, C> extends GenericyDemo3Father<A> implements GenericyDemo3Iface<B> { private static final String ParameterizedType = null; private C c; @Override public String test(B t) { return t.toString(); } private <T> T test3(T t) { return t; } public static void main(String[] args) { Type[] genericInterfaces = GenericyDemo3.class.getGenericInterfaces(); System.out.println(genericInterfaces[0]); Type superclass = GenericyDemo3.class.getGenericSuperclass(); if (superclass instanceof ParameterizedType) { Type[] actualTypeArguments = ((ParameterizedType) superclass).getActualTypeArguments(); System.out.println(actualTypeArguments[0]); } GenericyDemo3 genericyDemo3 = new GenericyDemo3(); try { Method[] methods = genericyDemo3.getClass().getDeclaredMethods(); for (Method method : methods) { if (method.getName().equals("test3")) { method.setAccessible(true); Object invoke = method.invoke(genericyDemo3, "String"); if (invoke.getClass() == String.class) { System.out.println(invoke);// 有输出String } } } } catch (Exception e) { e.printStackTrace(); } } } interface GenericyDemo3Iface<T> { public String test(T t); } class GenericyDemo3Father<T> { public String test1(T t) { return t.toString(); } }
4.泛型不写与书写Obejct的区别
public class GenericyDemo4 { //不写泛型默认为Object,编译时不会进行类型检查 //写泛型为Object,编译时会进行类型检查 public static void main(String[] args) { ArrayList arrayList = new ArrayList(); arrayList.add("a"); arrayList.add(1); ArrayList<Object> arrayList1= new ArrayList<>(); arrayList1.add("a"); arrayList1.add(1); } }
5.获取泛型的类型
public class GenericyDemo5 { public static void main(String[] args) throws Exception { Method[] methods = GenericyDemo5Test.class.getMethods(); for (Method method : methods) { if (method.getName().equals("test")) { Type[] parameterTypes = method.getGenericParameterTypes(); System.out.println(parameterTypes[0]); } } } } class GenericyDemo5Test { public Vector<String> test(Vector<String> Str) { return null; } }
6.泛型的拭除
public class GenericyDemo6 { public static void main(String[] args) { ArrayList<String> arrayList = new ArrayList<>(); ArrayList<Integer> arrayList1 = new ArrayList<>(); System.out.println(arrayList.getClass()==arrayList1.getClass());//true,在编译后会拭除泛型 } }
7.通配符的特征:
1)可以用于声明类型和声明方法的参数上,实例化时需指定,不可以用于声明类的参数上;
2)?只能输入和输出,不能修改;
3)? extends 上限 (继承或者实现关系);
4)? super 下限 (继承或者实现关系,可以是下限或者是下限的子类);
public class GenericyDemo7 { public static void main(String[] args) { ArrayList<? super List<String>> arrayList1 = new ArrayList<>(); arrayList1.add(new ArrayList<>());//不能添加new Object(); 原因前面已经说明 } }
public class GenericyDemo7 { public static void main(String[] args) { ArrayList<? extends GenericyDemo7Iface> list1 = new ArrayList<>(); ArrayList<GenericyDemo7Son> list2 = new ArrayList<>(); list2.add(new GenericyDemo7Son()); list1=list2; System.out.println(list1.get(0)); //list1.add(new GenericyDemo7Son());//编译错误,只能添加null值 } } class GenericyDemo7Son implements GenericyDemo7Iface { } interface GenericyDemo7Iface { }
8.同一个类型不能实现相同的接口
//不能使用GenericyDemo9Iface<GenericyDemo9Fater> 因为会将GenericyDemo9Father泛化成GenericyDemo9Iface<GenericyDemo9Fater>相同的接口 //public class GenericyDemo9 extends GenericyDemo9Father implements GenericyDemo9Iface<GenericyDemo9>{ // public static void main(String[] args) { // System.out.println(1); // } //} // //class GenericyDemo9Father implements GenericyDemo9Iface{ // //} // //interface GenericyDemo9Iface<GenericyDemo9Father>{ //}
//可以如下使用 public class GenericyDemo8 extends GenericyDemo8Father implements GenericyDemo8Iface{ public static void main(String[] args) { System.out.println(1); } } class GenericyDemo8Father implements GenericyDemo9Iface{ } interface GenericyDemo8Iface{ }
9.new integer()不属于Integer类型
public class GenericyDemo12 { // public Integer test(){ // return new Integer();//编译错误 // } public Integer test(){ return new Integer(0);//编译通过 } }
class ClassAsFactory<T> { T x; public ClassAsFactory(Class<T> kind) { try { x = kind.newInstance(); } catch(Exception e) { throw new RuntimeException(e); } } } class Employee {} public class InstantiateGenericType { public static void main(String[] args) { //运行时通过 ClassAsFactory<Employee> fe = new ClassAsFactory<Employee>(Employee.class); System.out.println("ClassAsFactory<Employee> succeeded"); try { //运行时异常 ClassAsFactory<Byte> fi = new ClassAsFactory<Byte>(Byte.class); } catch(Exception e) { System.out.println("ClassAsFactory<Byte> failed"); } } }
10.编译过程中的问题
public class GenericyDemo11<T extends Pet> { //方式1,类型检查无效 // public void test(ArrayList list){ // list.add(new Cat()); // } // public static void main(String[] args) { // ArrayList<Dog> list = new ArrayList<>(); // GenericyDemo11<Pet> genericyDemo11 = new GenericyDemo11<>(); // genericyDemo11.test(list); // } //方式2 public void test(List list){ list.add(new Cat()); } public static void main(String[] args) { // Dog.class可以是多态的方式 List<Dog> checkedList = Collections.checkedList(new ArrayList<Dog>(), Dog.class); GenericyDemo11<Pet> genericyDemo11 = new GenericyDemo11<>(); try { genericyDemo11.test(checkedList); } catch (Exception e) { System.out.println("list.add类型不正确"); } } } class Pet { } class Cat extends Pet{ } class Dog extends Pet{ }