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]
*/