java泛型擦除的神秘之处,边界处的动作,擦除的补偿

31 篇文章 0 订阅

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


  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论

打赏作者

java的爪哇

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值