`
jiabao523527
  • 浏览: 7652 次
  • 性别: Icon_minigender_1
  • 来自: 天津
最近访客 更多访客>>
社区版块
存档分类
最新评论

黑马程序员_泛型之初体验

阅读更多

  ------- android培训java培训、期待与您交流! ----------

 

1. 什么是泛型?
泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。可以在集合框架(Collection framework)中看到泛型的动机。泛型最大的优点就是消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中,同时提高Java 程序的类型安全,增强程序的可靠性!

2.泛型基础

2.1类型参数
定义泛型类或声明泛型类的变量时,使用尖括号来指定形式类型参数。

public class GenericsDemo14{  
   public static void main(String args[]){  
       Info<String> i = new Info<String>() ;       // 使用String为泛型类型  
        i.setVar("it") ;                            // 设置内容  
       fun(i) ;  
   }  

2.2命名类型参数
推荐的命名约定是使用大写的单个字母名称作为类型参数

推荐的名称是:
K —— 键,比如映射的键。
V —— 值,比如 List 和 Set 的内容,或者 Map 中的值。
 E —— 异常类。
T —— 泛型。

class Notepad<K,V>{       // 此处指定了两个泛型类型  
    private K key ;     // 此变量的类型由外部决定  
    private V value ;   // 此变量的类型由外部决定  
    public K getKey(){  
        return this.key ;  
    }  
   public V getValue(){  
        return this.value ;  
   }  
   public void setKey(K key){  
        this.key = key ;  
    }  
    public void setValue(V value){  
        this.value = value ;  
   }  
} 

2.3类型通配符

引入了类型通配符,可以声明 List<?> 类型的变量。

假设您具有该方法:

void printList(List l) {
for (Object o : l)
System.out.println(o);
}

 
上面的代码在 JDK 5.0 上编译通过,但是如果试图用 List<Integer> 调用它,则会得到警告。出现警告是因为,您将泛型(List<Integer>)传递给一个只承诺将它当作 List(所谓的原始类型)的方法,这将破坏使用泛型的类型安全。
如果试图编写像下面这样的方法,那么将会怎么样?

void printList(List<Object> l) {
for (Object o : l)
System.out.println(o);
}

 它仍然不会通过编译,因为一个 List<Integer> 不是 一个 List<Object>。这才真正烦人 —— 现在您的泛型版本还没有普通的非泛型版本有用!
解决方案是使用类型通配符:

void printList(List<?> l) {
for (Object o : l)
System.out.println(o);
}

上面代码中的问号是一个类型通配符。它读作“问号”。List<?> 是任何泛型 List 的父类型,所以您完全可以将 List<Object>、List<Integer> 或 List<List<List<Flutzpah>>> 传递给 printList()。

2.4 泛型方法
在类的定义中添加一个形式类型参数列表,可以将类泛型化。方法也可以被泛型化,不管它们定义在其中的类是不是泛型化的。

class Demo{
	public <T> T fun(T t){	 // 可以接收任意类型的数据
		return t ;	 // 直接把参数返回
         }
  }
-------------------------------------------------------------------------------------
/*泛型方法不一定要通过参数来确定泛型准确类型,可以只通过返回值*/
public static  ArrayList<E> newArrayList() {
    return new ArrayList<E>();
  }
    public List<PrepaidHistory> queryHistories(Long skyid,PrepaidHistoryType type, Date from, Date end) {

    。。。
        return Lists.newArrayList();//智能的知道返回类型为repaidHistory
    }

2.5有限制类型

可以对类型进行限定:
 ? extends E:接收E类型或者E的子类型对象。上限!
? super E :接收E类型或者E的父类型。下限!

class Info<T extends Number>{	// 指定上限,只能是数字类型
	private T var ;		// 此类型由外部决定
	public T getVar(){
		return this.var ;	
	}
	public void setVar(T var){
		this.var = var ;
	}
	public String toString(){	// 覆写Object类中的toString()方法
		return this.var.toString() ;	
	}
}
public class GenericsDemo27{
		public static <T extends Number> Info<T> fun(T param){//方法中传入或返回的泛型类型由调用方法时所设置的参数类型决定
		Info<T> temp = new Info<T>() ;		// 根据传入的数据类型实例化Info
		temp.setVar(param) ;		// 将传递的内容设置到Info对象的var属性之中
		return temp ;	// 返回实例化对象
	}
}
public static void printCollection(Collection<? super Student> al){

		Iterator<? super Student> it = al.iterator();
		//接受student类型或它的父类型。
		while(it.hasNext()){
			
			System.out.println(it.next());
		}
	}

 

 2.6泛型数组

public class GenericsDemo30{
	public static void main(String args[]){
		Integer i[] = fun1(1,2,3,4,5,6) ;	// 返回泛型数组
		fun2(i) ;
	}
	public static <T> T[] fun1(T...arg){	// 接收可变参数
		return arg ;		// 返回泛型数组
	}
	public static <T> void fun2(T param[]){	// 输出
		System.out.print("接收泛型数组:") ;
		for(T t:param){
			System.out.print(t + "、") ;
		}
	}
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics