u010708662的专栏

有一块学习android的可以加qq490282645,共享学习资源。

java(16) - 泛型

一.泛型:

       泛型是JDK1.5中一个重要的特征。

         泛型:泛型就是变量类型的参数化。

         因为泛型的引入让集合类框架避免了运行时抛出的ClassCastExceptions,当编译时不出错,则运行时就不会出错。所以java的大部分类库都已经泛型化了。

         java泛型的主要目的是建立具有类型安全的数据结构,在使用泛型类建立的数据结构时,不必进行强制类型转换。

         简单实现:

 

        

public class GenericTest<T> {
        private T  generic;

	public T getGeneric() {
		return generic;
	}

	public void setGeneric(T generic) {
		this.generic = generic;
	}
	public static void main(String[] args) {
		
		GenericTest<String>  generic  =  new  GenericTest<String>();
		
		generic.setGeneric(new String("A"));
		
		System.out.println(generic.getGeneric());
	}
}
打印  
     A

       此例中的类后尖括号中T就是泛型,它就可以变量类型的参数化。 当GenericTest<String>  generic  =  new  GenericTest<String>()中的尖括号中声明了String类型,set进对象时只能是String类型。当传入别的类型对象时则会编译出错。

     例子:

  

 

    我们让泛型为String类型,再传入其他类型则会报错。

 

 

      其中的T可以被替换成任何一个合理的标示符,泛型的声明方式:class  类名<泛型列表>。泛型可以是任何对象和接口,但不能是基本数据类型。当使用泛型类声明对象时,必须指定类中使用的泛型的具体实际类型,也就是如GenericTest<String>  generic  =  new  GenericTest<String>()。

   


         之前我们讲过的集合类框架,他们都必须有泛型,因为没有用泛型,所以需要向下类型转换,而且其中的类型安全不能得到保证,对于一个集合中的类型,都应该是同一种类型,而不是既有字符串,又有整型,这样非常的不规范。

        所以正确的使用集合应该是这样(前面先讲集合类好理解,再学习泛型比较容易):

  先从ArrayList开始:

ArrayList:

public class ArrayListTest {
   
	public static void main(String[] args) {
	
	      List<String> array = new ArrayList<String>();
	      
	      
	      array.add(new String("Ane"));
	      array.add(new String("Two"));
	      array.add(new String("Three"));
	     
	      // 如果在往集合中添加其他类型就会编译报错.  
	      // array.add(new Integer(1));这样就会报错
	      
	      Iterator<String> i = array.iterator();
	      while(i.hasNext()){
	    	  
	    	  System.out.println(i.next());
	    	  
	      }
	   
	   
     }
}
Ane
Two
Three

 

LinkedList:

public static void main(String[] args) {
	
	      List<String>   array = new LinkedList<String>();
	      
	      
	      array.add(new String("Ane"));
	      array.add(new String("Two"));
	      array.add(new String("Three"));
	     
	      // 如果在往集合中添加其他类型就会编译报错.  
	      // array.add(new Integer(1));这样就会报错
	      
	      Iterator<String> i = array.iterator();
	      while(i.hasNext()){
	    	  
	    	  System.out.println(i.next());
	    	  
	      }
	   
	   
     }
}
Ane
Two
Three


HashSet:

public class ArrayListTest {
   
	public static void main(String[] args) {
	
	      Set<String> set=  new HashSet<String>();
	      
	      set.add("A");
	      set.add("B");
	      set.add("C");
	      
	      Iterator<String> i = set.iterator();
	      while(i.hasNext()){
	    	  
	    	  System.out.println(i.next());
	    	  
	      }
	   
	   
     }
}
A
B
C

 

当泛型列表为:class 类名<T,E>时,与前面理解还是一样的。

HashMap:

public class Test {
		public static void main(String[] args) {
	         
			 HashMap<String,Integer>  map = new HashMap<String,Integer>();
			 map.put("1",1);
			 map.put("2",2);
			 map.put("3",3);
			 map.put("4",4);
			 
			 Iterator<Map.Entry<String,Integer>> iter = map.entrySet().iterator();//返回enter
			 
			 while(iter.hasNext()){
				 Map.Entry<String,Integer> entry= (Map.Entry<String,Integer>)iter.next();
				 String key = entry.getKey();
				 int value = entry.getValue();
				 
				 System.out.println(key+":"+value);
			 }
		}
}
打印:
3:3
2:2
1:1
4:4

 

创建类时指定泛型接口以下类别:

 

public class Test<T extends List> { //指定只能为List的子类
	private T foo;
    
	public T getFoo() {
		
		return foo;
    	
	}
	public void setFoo(T foo) {
		
		this.foo = foo;
	
	}
	public static void main(String[] args) {
	    
		Test<ArrayList<String>> arr = new Test<ArrayList<String>>();//只可以以List的子类当泛型
		
		//Test<HashSet> set = new Test<HashSet>();因为HashSet不是List的子类,所以会出错误。
			
			 
	}
}




在声明一个引用时指定该引用可以使用什么的类型:

 

public class Test<T> { 
	private T foo;
    
	public T getFoo() {
		
		return foo;
    	
	}
	public void setFoo(T foo) {
		
		this.foo = foo;
	
	}
	public static void main(String[] args) {
	    
			Test<? extends List> arr = null;//在声明引用时可以指定该引用使用什么类型,但必须是其子类型
			arr = new Test<ArrayList<String>>();
			arr = new Test<LinkedList<String>>();
			 
	}
}

<? super List> 这就是指定其List的上的父类。

上面这种通配符使用注意 :

     1.实例化持有者时,它必须是实现List的类别或其子类别。

     2.当使用<?>或者<? extends SomeClass>的声明方式,意味着你只能通过该名称来取得所参考的实例信息,或者是移除某些信息,但不能增加它的信息,因为你只是知道其中放置的是SomeClass的子类,但你不知道是什么类,所以编译起不让你添加信息。如果可以放入信息,那么您就得记住放入时方的是什么类型,取出时要强制转换,这就失去了泛型的意义。

     3.<?> 等价于 <? extends Object>

例:

从图上就可以看出其中T未指定什么类型。所以不能进行修改其中的内容。

 



 

 

         

 

阅读更多
文章标签: java
个人分类: java
上一篇java(15)-策略模式(Strategy Pattern)
下一篇java(17) - 增强for循环、装箱拆箱、可变参数
想对作者说点什么? 我来说一句

Java Generics and Collections

2018年05月09日 2.13MB 下载

关于java泛型的讲解

2011年06月15日 63KB 下载

java泛型机制

2011年11月06日 35KB 下载

JAVA泛型集合

2018年04月26日 3.76MB 下载

全面总结Java泛型

2009年12月17日 81KB 下载

java泛型学习ppt

2011年08月01日 829KB 下载

没有更多推荐了,返回首页

关闭
关闭