java(16) - 泛型(一)

2014-11-24 08:05:17 · 作者: · 浏览: 0

一.泛型:

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

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

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

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

简单实现:

public class GenericTest
  
    {
        private T  generic;

	public T getGeneric() {
		return generic;
	}

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

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

例子:

\

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

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


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

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

先从ArrayList开始:

ArrayList:

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

LinkedList:

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

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

HashMap:

public class Test {
		public static void main(String[] args) {
	         
			 HashMap
  
     map = new HashMap
   
    (); map.put("1",1); map.put("2",2); map.put("3",3); map.put("4",4); Iterator
    
     > iter = map.entrySet().iterator();//返回enter while(iter.hasNext()){ Map.Entry
     
       entry= (Map.Entry
      
       )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
  
    { //指定只能为List的子类
	private T foo;
    
	public T getFoo() {
		
		return foo;
    	
	}
	public void setFoo(T foo) {
		
		this.foo = foo;
	
	}
	public static void main(String[] args) {
	    
		Test
   
    > arr = new Test
    
     >();//只可以以List的子类当泛型 //Test
     
       set = new Test
      
       ();因为HashSet不是List的子类,所以会出错误。 } } 
      
     
    
   
  




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

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

这就是指定其List的上的父类。

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

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

2.当使用 或者 的声明方式,意味着你只能通过该名称来取得所参考的实例信息,或者是移除某些信息,但不能增加它的信息,因为你只是知道其中放置的是SomeClass的子类,但你不知道是什么类,所以编