java泛型擦除的神秘之处
package org.rui.generics.erasure; public class HasF { public void f(){ System.out.println("hasf.f"); } }
package org.rui.generics.erasure; /** * 边界 <T extneds Hasf>声明T必须具有类型HasF或者从Hasf导出的类型。 * 如果情况确实如此,那么就可以安全地在obj上调用f()了 * T擦除了 HasF * @author lenovo * * @param <T> */ //class Manipulator<T> Error: 不能调用obj.f() class Manipulator<T extends HasF> { private T obj; public Manipulator(T x){obj=x;} public void manipulate(){obj.f();} //获取泛型类型 public T getGenType(){return obj;} } public class Manipulation<T> { public static void main(String[] args) { HasF h=new HasF(); Manipulator<HasF> man=new Manipulator<HasF>(h); man.manipulate(); System.out.println("genType:"+man.getGenType().getClass()); } } /**output: hasf.f genType:class org.rui.generics.erasure.HasF */
package org.rui.generics.erasure; import java.lang.reflect.Array; import java.util.Arrays; /** * 边界处的动作 * 即失kind被存储为Class<T> 擦除也意味着它实际将被存储为 Class,没有任何参数 * @author lenovo * */ public class ArrayMaker<T> { private Class<T> kind; public ArrayMaker(Class<T> kind) { this.kind=kind; } @SuppressWarnings("unchecked") T[] create(int size) { return (T[])Array.newInstance(kind, size); } public static void main(String[] args) { ArrayMaker<String> maker=new ArrayMaker<String>(String.class); String[] stringArray=maker.create(9); System.out.println(Arrays.toString(stringArray)); } } /**output: * [null, null, null, null, null, null, null, null, null] */
package org.rui.generics.erasure; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * 边界处的动作 * 容器而不是数组 情况不不同了 * @author lenovo * */ public class ListMaker<T> { /*private Class<T> kind; public ListMaker(Class<T> kind) { this.kind=kind; }*/ List<T> create(T t,int n) { List<T> list= new ArrayList<T>(); for(int i=0;i<n;i++) list.add(t); return list; } public static void main(String[] args) { ListMaker<String> maker=new ListMaker<String>(); List<String> str=maker.create("hello",4); System.out.println(str); } }
package org.rui.generics.erasure; /** * 擦除的补偿 * * 编译器将确保类型标签可以匹配泛型参数 * @author lenovo * */ class Building{} class House extends Building{} public class ClassTypeCapture<T> { Class<T> kind; public ClassTypeCapture(Class<T> kind) { this.kind=kind; } public boolean f(Object obj) { System.out.println(kind +" isInstance "+obj); return kind.isInstance(obj); } public static void main(String[] args) { ClassTypeCapture<Building> ctc= new ClassTypeCapture<Building>(Building.class); System.out.println(ctc.f(new Building())); //父类 与子对比 System.out.println(ctc.f(new House())); ClassTypeCapture<House> ctc2= new ClassTypeCapture<House>(House.class); //House is building 子对比父=false System.out.println(ctc2.f(new Building())); System.out.println(ctc2.f(new House())); } } /** output: true true false true */
package org.rui.generics.erasure; /** * 创建类型实例 * * @author lenovo * */ class ClassAsFactory<T> { T x; public ClassAsFactory(Class<T> kind) { try { x=kind.newInstance(); } catch (Exception e) { e.printStackTrace(); } } } //////////////////////////////////// class Employee{} public class InstantiateGenericType { public static void main(String[] args) { ClassAsFactory<Employee> caf= new ClassAsFactory<Employee>(Employee.class); System.out.println("caf:"+caf.x); /*try { //Integer 没有默认的构造器 ClassAsFactory<Integer> cafInt= new ClassAsFactory<Integer>(Integer.class); } catch (Exception e) { System.out.println("ClassAsFactory<Integer> failed"); }*/ } }
package org.rui.generics.erasure; interface FactoryI<T> { T create(); } class Foo2<T> { private T x; public <F extends FactoryI<T>> Foo2(F f) { x=f.create(); } } /////////////////////////////////////////////////////////////////// class IntegerFactory implements FactoryI<Integer> { public Integer create() { return new Integer(0); } } /////////////////////////////////////////////////////////////////// class Widget { public static class Factory implements FactoryI<Widget> { public Widget create() { return new Widget(); } } } /////////////////////////////////////////////////////////////////// public class FactoryConstraint { public static void main(String[] args) { new Foo2<Integer>(new IntegerFactory()); new Foo2<Widget>(new Widget.Factory()); } }
package org.rui.generics.erasure; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; class Frob{} class Fnorkle{} class Quark<Q>{} class Particle<POSITION,MOMENTUM>{}; /** * java 泛型是使用擦除来实现的 * 在泛型代码内部,无法获得任何有关泛型 参数类型信息 * @author lenovo * */ public class LostInformation { public static void main(String[] args) { List<Frob> list=new ArrayList<Frob>(); Map<Frob,Fnorkle> map=new HashMap<Frob,Fnorkle>(); Quark<Fnorkle> quark=new Quark<Fnorkle>(); Particle<Long,Double> p=new Particle<Long,Double>(); System.out.println(Arrays.toString( list.getClass().getTypeParameters())); System.out.println(Arrays.toString( map.getClass().getTypeParameters())); System.out.println(Arrays.toString( quark.getClass().getTypeParameters())); System.out.println(Arrays.toString( p.getClass().getTypeParameters())); } } /*output: [E] [K, V] [Q] [POSITION, MOMENTUM] */