zoukankan      html  css  js  c++  java
  • Java -- 泛型

    1. 泛型: 允许在定义类,接口时指定类型形参,这个类型形参将在声明变量,创建对象时确定(即传入实际的类型参数,也可以成为类型实参)。

    如下示例:  可以对泛型形参做限制 class A<T extends C>{}, T就只能是C的子类。可以用extends设置上限,就可以用super设置下限 <? super T>,对应T或者T的父类。

    class A<T>  // <T>为泛型, 不必在意T的实际类型,这只是一个类型形参
    {
    	T info;	
    }
    
    class B extends A<Double>   //泛型类继承的时候需要明确参数类型
    {	
    }
    
    public class Main {		
    	public static void main(String[] args) {
    		
    		A<String> a = new A<String>(); //定义变量时 确定泛型类型 为String
    		a.info = "hello_world";
    		System.out.println(a.info);
    
    		B b = new B();   //继承时确定泛型为Double
    		b.info = 3.14159;
    		System.out.println(b.info);				
    	}	
    }


    2. 不管泛型类型的实际类型参数是什么,他们在运行时总是有同样的类,系统中并不会真真生成泛型类。类的静态变量和静态方法在所有实例中共有,所以不能用静态修饰泛型变量。

    3. 泛型通配符, 由于有泛型类的存在,所有当泛型类做形参是,有可能并不能确定形参的类型,这时就可以用泛型通配符?。

    同时可以限制通配符  void testB(A<? extends C>){}   , 这样泛型参数类型就只能是C的子类。

    如果Foo是Bar的一个子类,而G是有泛型声明的接口 或者 类,那么G<Foo>并不是G<Bar>的子类。

    class A<T>
    {
    	T info;	
    }
    
    class B 
    {
    	void testB(A<?> a)  //并不能确定形参的类型,可以用 泛型通配符 ? 
    	{
    		System.out.println(a.info);
    	}	
    }
    
    public class Main {		
    	public static void main(String[] args) {
    		
    		A<String> a1 = new A<String>();
    		A<Double> a2 = new A<Double>();
    		a1.info = "hello_world";
    		a2.info = 3.14159;
    		B b1 = new B();
    		b1.testB(a1);
    		b1.testB(a2);		
    	}	
    }

    如下:  

      ArrayList<?> list = new ArrayList<String>();
      list.add("hello"); //报错

    泛型通配符 只是表示各泛型List的父类,并不能把元素加进去。


    4. 泛型方法,在声明时定义一个或多个类型形参,

    格式:  修饰符 <T, S >  返回值类型 方法名(形参列表) { 。。。 }

    class A<T>
    {
    	T info;	
    }
    
    class B 
    {
    	void testB(A<?> a)   //泛型通配符
    	{
    		System.out.println(a.info);
    	}	
    }
    
    class C
    {
    	static <T> void testC(T t)   //泛型方法
    	{
    		System.out.println(t);
    	}
    }
    
    public class Main {		
    	public static void main(String[] args) {
    		
    		A<String> a1 = new A<String>();
    		A<Double> a2 = new A<Double>();
    		a1.info = "hello_world";
    		a2.info = 3.14159;
    		B b1 = new B();
    		b1.testB(a1);
    		b1.testB(a2);
    		
    		String t1 = new String("hello");
    		Double t2 = new Double(3.14);
    		C.testC(t1);
    		C.testC(t2);		
    	}	
    }

     从上可以看出 泛型通配符和泛型方法 用法上有很多交集,但如果某个方法中一个形参a的类型依赖于 另一个形参b的类型,则形参b的类型声明不能用通配符。因为b的类型无法确定的话,程序无法定义形参a的类型。

    5.  泛型类和反射泛形

    如果一个类多处都要用到同一个泛型,这时可以把泛形定义在类上(即类级别的泛型),语法格式如下:

      public class GenericDao<T> {

      private T field1;

      public void save(T obj){}

      public T getId(int id){}

      }

    注意,静态方法不能使用类定义的泛形,而应单独定义泛形。

     

    泛形的典型应用:BaseDao和反射泛型:

    //基本Dao
    public abstract class BaseDao<T> {
    
    	private Session session;
    	private Class clazz;
    	
    	
    	//哪个子类调的这个方法,得到的class就是子类处理的类型(非常重要)
    	public BaseDao(){
    		Class clazz = this.getClass();  //拿到的是子类
    		ParameterizedType  pt = (ParameterizedType) clazz.getGenericSuperclass();  //BaseDao<Category>
    		clazz = (Class) pt.getActualTypeArguments()[0];
    		System.out.println(clazz);
    		
    	}
    	
    
    	public void add(T t){
    		session.save(t);
    	}
    	
    	public T find(String id){
    		return (T) session.get(clazz, id);
    	}
    	
    	public void update(T t){
    		session.update(t);
    	}
    	
    	public void delete(String id){
    		T t = (T) session.get(clazz, id);
    		session.delete(t);
    	}
    	
    }
    public class BookDao extends BaseDao<Book> {
    // 子类Dao
    }



     

  • 相关阅读:
    快速构建Windows 8风格应用22MessageDialog
    快速构建Windows 8风格应用20MediaElement
    Windows Phone SDK 8.0安装步骤
    快速构建Windows 8风格应用25数据绑定
    快速构建Windows 8风格应用24App Bar构建
    快速构建Windows 8风格应用21构建简单媒体播放器
    快速构建Windows 8风格应用23App Bar概述及使用规范
    sqlyog存储过程
    201751201 输入数字输出汉字读法
    考虑算法的时间效率
  • 原文地址:https://www.cnblogs.com/xj626852095/p/3648078.html
Copyright © 2011-2022 走看看