关闭

Java基础&增强 泛 型

283人阅读 评论(0) 收藏 举报
分类:

           ---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------


          Java中的范型使用起来特别轻松:

         

   List<String> list = new ArrayList<String>();
       list.add("abc"); // ok !
       //list.add(123); error!

    这仅仅是泛型的最简单的应用,我们知道,java的泛型是编译时会擦除的:

        

ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(100);
		list.add(200);
		list.add(300);
		Class<?> clazz = list.getClass();
		Method method = clazz.getMethod("add", Object.class);
		method.invoke(list, "哈哈");
		for(int i=0; i<list.size(); i++){
			System.out.print(list.get(i) + " ");
		}
    通过反射在运行时给list添加元素,此时泛型已经擦除,所以可以添加String类型的元素了。

    这下打印出来的结果是 : 100 200 300 哈哈

    说到底,泛型可以让我们在实际编程时不容易出错,但是要真正用好泛型也不是很容易的事:

      定义一个接口:

      

public interface Stack<T> {	
	public T pop();
	public void push(T t);
	public void pushAll(Iterable<T> it);
	public void popAll(Collection<T> coll);
}

      实现类:

   

public class MyStack<T> implements Stack<T>{
	
	

	public T pop() {
		return this.list.remove(0);
	}

	public void push(T t) {
		this.list.add(0, t);
	}
    
	
	public void pushAll(Iterable<T> it) {
		for(T t : it){
			this.push(t);
		}
	}

	
	public void popAll(Collection<T> coll) {
		while(list.size() != 0){
			coll.add(this.pop());
		}
	}
	
	private List<T> list = new ArrayList<T>();

}

接下来使用该类:

  

Stack<Number> stack = new MyStack<Number>(); 
		stack.push(1);

看起来ok,继续:

List<Integer> integers = new ArrayList<Integer>();
		stack.pushAll(integers);
此时编译器就通不过了,报出了 : Stack<Number> connot be applied to (Interable<Integer>) 错误

我的想法是:  pushAll的参数不应该是T的Iterable接口,应该是T的某个子类型的Iterable接口,正好,java中有一个通配符正合此意,于是将代码改成下面这样:

/*
	 * 此处如果是Iterable<T>编译时会报错,此处我们的希望是T的某种子类型的Iterable接口而不是T的Iterable接口 
	 */
	public void pushAll(Iterable<? extends T> it) {
		for(T t : it){
			this.push(t);
		}
	}

ok,正常了,继续:

Collection<Object> coll = new ArrayList<Object>();
		stack.popAll(coll);

此时又不通过了,报出了: Collection<Object> 不是 Collection<Number>的子类型,这和刚才的错误差不多,我的意思不是T的集合,而是T的某种超类的集合,java也正好有个通配符正符合此意,于是将代码改成这样:

/*
	 *Collection<T> 编译时会出错,我们此处的愿望是T的某种超类的集合而不是T的集合
	 */
	public void popAll(Collection<? super T> coll) {
		while(list.size() != 0){
			coll.add(this.pop());
		}
	}
ok,正常了,在整体性的试一试:


Stack<Number> stack = new MyStack<Number>(); 
		stack.push(1);
		stack.push(2);
		stack.push(3);
		stack.push(4);
		List<Integer> integers = new ArrayList<Integer>();
		stack.pushAll(integers);
		Collection<Object> coll = new ArrayList<Object>();
		System.out.println(stack.pop());
		stack.popAll(coll);
		for(Object obj : coll){
			System.out.println(obj);
		}
嗯,一切OK!!!

java中泛型我觉得有一种很好的用法 :  类型安全的异构容器:

public interface Favorite {	
	public <T> void putFavorite(Class<T> type,T instance);
	public <E> E getFavorite(Class<E> type);
}
实现类非常非常简单:

public class MyFavorite implements Favorite{
	
	public <T> void putFavorite(Class<T> type,T instance){
                if(type == null){
		    throw new NullPointerException("type为空!");
		}
		map.put(type, instance);
	}
	/*
	 * getFavorite方法 使用了Class的cast方法,将对象动态的转换成了Class对象所表示的类型
	 * 该方法只检验它的参数是否为Class对象所表示的类的是咧,如果是则返回参数,否则就抛出ClassCastException异常
	 */
	
	public <E> E getFavorite(Class<E> type){ 
		return type.cast(map.get(type));
	}
	
	Map<Class<?>,Object> map = new HashMap<Class<?>,Object>();

}

我来试试好不好用:

          Favorite favorite = new MyFavorite();
          favorite.putFavorite(String.class, "哈哈");
	  favorite.putFavorite(Integer.class, 100);
		
	  System.out.print(favorite.getFavorite(String.class) + " ");
	  System.out.print(favorite.getFavorite(Integer.class));


输出结果:  哈哈  100   


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:2883次
    • 积分:111
    • 等级:
    • 排名:千里之外
    • 原创:9篇
    • 转载:0篇
    • 译文:0篇
    • 评论:0条
    文章分类
    文章存档