Java基础&增强 泛 型

原创 2013年12月02日 20:26:34

           ---------------------- 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   


java泛性

为什么会有泛型呢? 早期的Object类型可以接收任意的对象类型,但是在实际的使用中,会有类型转换的问题。也就存在这隐患,所以Java提供了泛型来解决这个安全问题。 package...
  • u014401141
  • u014401141
  • 2017年04月30日 18:36
  • 302

泛 型(java基础学习)

java中泛型的基础讲解,对于android开发中也起到重要作用,这只是一个学习的基础。...
  • yate2008
  • yate2008
  • 2017年06月20日 08:45
  • 89

java基础增强之其他小知识

---------------------- ASP.Net+Android+IO开发S、.Net培训、期待与您交流! ---------------------- 1.静态导入 概念:当我们想调用...
  • zhoulenihao
  • zhoulenihao
  • 2013年09月10日 13:36
  • 1244

传智播客-Java基础加强-day5

注解:也是jdk1.5的一个新特性,是一种标记,一种说明,可以在包,类,方法,参数,成员变量等对象或成员之前,javac编译器,开发工具和其它程序可以用反射来了解类及各种元素上是否有某种标记,不同的标...
  • aasspp1100
  • aasspp1100
  • 2011年01月13日 23:19
  • 297

Java基础:基础加强

Java enhance
  • zr523725410
  • zr523725410
  • 2014年09月26日 00:24
  • 2309

黑马程序员-张孝祥Java基础加强(PART1)

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ---------------------- 知识点: 1.Java5的几个新特性,...
  • niniliwei
  • niniliwei
  • 2014年02月28日 15:30
  • 1081

泛型指针,原生指针和智能指针

泛型指针,原生指针和智能指针 1. 泛型指针 泛型指针有多种含义。 (1) 指void*指针,可以指向任意数据类型,因此具有“泛型”含义。 (2) 指具有指针特性的泛型数据结构...
  • autumn20080101
  • autumn20080101
  • 2016年08月11日 19:55
  • 129

泛 型

第15章 泛 型 一般的类和方法,只能使用具体的类型,要么是基本类型,要么是自定义的类。如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大。 在面向对象的编程语言中,多态算是一...
  • qq_26122707
  • qq_26122707
  • 2017年01月30日 13:46
  • 144

java实现泛域名解析,附SpringMVC源码示例

所谓“泛域名解析”是指:利用通配符 * (星号)来做次级域名以实现所有的次级域名均指向同一IP地址。例如支付宝的域名是www.alipay.com域名下面有帮助中心help.alipay.com 、a...
  • lywybo
  • lywybo
  • 2010年07月08日 20:58
  • 7869

Kotlin-15.泛型(generics)

Kotlin类也有类型参数泛型generics;型变(Variance);Java泛型通配符;型变Variance;声明处型变Declaration-site variance;out, in修饰符;...
  • qq_32115439
  • qq_32115439
  • 2017年06月24日 00:09
  • 344
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java基础&增强 泛 型
举报原因:
原因补充:

(最多只允许输入30个字)