从头认识java-13.7 什么时候使用泛型?

这一章节我们来讨论一下什么时候使用泛型?

答案:当你希望代码能够跨多个类型(不同的类型,不包含继承关系)工作的时候。

1.当没有确切类型的时候

下面是错误的代码:

package com.ray.ch13;

public class Test<T> {

	private T obj;

	public Test(T t) {
		obj = t;
	}

	public void test() {
		// obj.f();//error
	}
}


从上面的代码可以看出,在没有确切类型的时候,obj是不能调用任何方法。


正确的代码:

package com.ray.ch13;

public class Test<T extends Person> {

	private T obj;

	public Test(T t) {
		obj = t;
	}

	public void test() {
		obj.say();
	}
}

class Person {
	public void say() {
	}
}

只有当我们明确了泛型的边界,这个时候obj才能调用相关的方法。


出现上面的原因主要是在编译期间,编译器不知道T具体的边界在哪里,需要制定边界,才能找到相应的类,从而检查是否包含相应方法,因为java里面的是伪泛型,在jvm层面是见不到参数类型的,因此必须在编译期间就已经检查类型安全。



2.当我们在相同类型或者具有继承关系类型的时候

引用我们上面的代码:

package com.ray.ch13;

public class Test<T extends Person> {

	private T obj;

	public Test(T t) {
		obj = t;
	}

	public void test() {
		obj.say();
	}
}

class Person {
	public void say() {
	}
}

上面代码里面的泛型其实不大起作用,而且增加了代码的阅读难度,其实我们可以修改成下面的代码,功能是一样的:

package com.ray.ch13;

public class Test {

	private Person person;

	public Test(Person person) {
		this.person = person;
	}

	public void test() {
		person.say();
	}
}

class Person {
	public void say() {
	}
}

修改过的代码更加简单明了,这个时候有人会说,上面的是extend,你这里没有,但是我们再增加一点东西看看:

package com.ray.ch13;

public class Test {

	private Person person;

	public Test(Person person) {
		this.person = person;
	}

	public void test() {
		person.say();
	}

	public static void main(String[] args) {
		new Test(new Man()).test();
	}
}

class Person {
	public void say() {
		System.out.println("i am a person");
	}
}

class Man extends Person {
	@Override
	public void say() {
		System.out.println("i am a man");
	}
}

我们建立一个继承Person的类,然后一样可以把他放到里面进行方法调用。


3.笔者遇到的比较典型的泛型例子,就是使用泛型的dao

下面是引用别人的dao设计,

具体地址:http://blog.csdn.net/lazy_p/article/details/5599650

//通用DAO接口: 

package com.baiyyy.util.dao; 

import java.io.Serializable; 
import java.util.Collection; 
import java.util.Iterator; 
import java.util.List; 

import org.hibernate.Criteria; 
import org.hibernate.LockMode; 
import org.hibernate.criterion.Criterion; 
import org.hibernate.criterion.DetachedCriteria; 

/** 
* 承有业务数据的基础访问接口 
* <p> 
* 承有CRUD (创建,读取,修改和删陿)基本数据的操作在这个接口中都是独立的_ 并且承有的DAO都可以使用这些基本实玿 
* 
* @author yongtree 
* 
* @date:2008-03-04 
*/ 
public interface IBaseDAO<T, ID extends Serializable> { 

  /*************************************************************************** 
   * -------------------基本棿索?增加?修改?删除操使---------------------------- * 
   **************************************************************************/ 

  // --------findById()方法是?过get(ID id)得到实体对象----------------------- 
  /** 
   * 通过ID来得到实体对豿 
   * 
   * @param id 
   *            实体对象的标识符 
   * @param lock 
   *            使用的锁模式 
   * @return 该主键忼对应的实体对象 
   */ 
  public T findById(ID id, LockMode lock); 

  /** 
   * 通过ID来得到实体对豿 
   * 
   * @param id 
   * @return T 
   */ 
  public T findById(ID id); 

  /** 
   * 通过ID来得到实体对豿(为兼容其他开发成员的原有程序,保留使甿) 
   * 
   * @param c 
   * @param id 
   * @return T 
   */ 
  public T findById(Class c, ID id); 

  // -------------loadById()是调用hibernate的load方法------------ 

  public T loadById(ID id); 

  /** 
   * 通过id load对象 
   * 
   * @param id 
   * @param lock 
   * @return 
   */ 
  public T loadById(ID id, LockMode lock); 

  /** 
   * 获取全部的实使 
   * 
   * @return 
   */ 
  public List<T> loadAll(); 

  /** 
   * 保存丿个实体对豿 
   * 
   * @param entity 
   */ 
  public T saveEntity(T entity); 

  /** 
   * 更新丿个实体对豿 
   * 
   * @param entity 
   */ 
  public void updateEntity(T entity); 

  public void updateEntity(T entity, LockMode lock); 

  /** 
   * 增加或更新集合中的全部实使 
   * 
   * @param entities 
   */ 
  public void saveOrUpdateAll(Collection<T> entities); 

  /** 
   * 删除丿个实使 
   * 
   * @param entity 
   * @throws Exception 
   */ 
  public void deleteEntity(T entity); 

  public void deleteEntity(T entity, LockMode lock); 

  /** 
   * 根据主键删除指定实体 
   * 
   * @param id 
   */ 
  public void deleteEntityById(ID id); 

  public void deleteEntityById(ID id, LockMode lock); 

  /** 
   * 批量删除 
   * 
   * @param entities 
   */ 
  public void deleteAll(Collection<T> entities); 

  /** 
   * 通过合并的方式更新对豿 
   * 
   * @param entity 
   *            void 
   */ 
  public void merge(T entity); 

  /*************************************************************************** 
   * ------------------------------使用HQL语句-------------------------------- * 
   **************************************************************************/ 

  /** 
   * 使用HQL语句进行对象的查诿 
   * 
   * @param hsql 
   *            查询语句 
   * @return 符合条件的对豿 
   */ 

  public T getEntity(String hsql); 

  /** 
   * 使用HQL语句进行查询 
   * 
   * @param hsql 
   *            查询语句 
   * @return 符合条件的对象集吿 
   */ 
  public List<T> getEntities(String hsql); 

  /** 
   * 使用带参数的HQL语句进行查询 
   * 
   * @param hsql 
   * @param obj 
   * @return 
   */ 
  public List<T> getEntities(String hsql, Object[] values); 

  public List<T> getEntities(String hql, int start, int number); 

  public List<T> getEntities(String hql, int start, int number, 
      Object[] values); 

  /** 
   * 使用命名的HQL语句棿索数捿 
   * 
   * @param queryName 
   * @return 
   */ 
  public List<T> findByNamedQuery(String queryName); 

  /** 
   * 使用带参数的命名HSQL语句棿索数捿 
   * 
   * @param queryName 
   * @param values 
   * @return 
   */ 
  public List<T> findByNamedQuery(String queryName, Object[] values); 

  /** 
   * 使用带命名参数的命名HSQL语句棿索数捿 
   * 
   * @param queryName 
   * @param paramNames 
   * @param values 
   * @return 
   */ 
  public List<T> findByNamedQuery(String queryName, String[] paramNames, 
      Object[] values); 

  /** 
   * 使用HQL语句棿索数据,返回 Iterator 
   * 
   * @param queryString 
   * @return 
   */ 
  public Iterator<T> iterate(String queryString); 

  /** 
   * 使用带参数HSQL语句棿索数据,返回 Iterator 
   * 
   * @param queryString 
   * @param values 
   * @return 
   */ 
  public Iterator<T> iterate(String queryString, Object[] values); 

  /*************************************************************************** 
   * -----------------------------Criteria动濁查诿---------------------------- * 
   **************************************************************************/ 

  /** 
   * 创建与会话无关的棿索标准对豿 
   */ 
  public DetachedCriteria createDetachedCriteria(); 

  /** 
   * 创建与会话绑定的棿索标准对豿 
   * 
   * @return 
   */ 
  public Criteria createCriteria(); 

  /** 
   * 使用指定的检索标准检索数捿 
   * 
   * @param criteria 
   * @return 
   */ 
  public List<T> findByCriteria(DetachedCriteria criteria); 

  /** 
   * 使用指定的检索标准检索数据,返回部分记录 
   * 
   * @param criteria 
   * @param firstResult 
   * @param maxResults 
   * @return 
   */ 
  public List<T> findByCriteria(DetachedCriteria criteria, int firstResult, 
      int maxResults); 

  /** 
   * 通过动濁查询条件进行查诿 
   * 
   * @param criterion 
   * @return List<T> 
   */ 
  @SuppressWarnings("unchecked") 
  public List<T> findByCriteria(Criterion... criterion); 

  /** 
   * 使用指定的检索标准检索数据,返回指定范围的记彿 
   * 
   * @param criteria 
   * @return 
   */ 
  public Integer getRowCount(DetachedCriteria criteria); 

  /** 
   * 使用指定的检索标准检索数据,返回指定统计倿 
   * 
   * @param criteria 
   * @param propertyName 
   * @param StatName 
   *            (max,min,avg,sum) 
   * @return 
   */ 
  public Object getStatValue(DetachedCriteria criteria, String propertyName, 
      String StatName); 

  /** 
   * 通过给定的一个对象,查找与其匹配的对象,表关联比较多时,用户可以自己根据霿要扩展? 
   * 
   * @param entity 
   * @return List<T> 
   */ 
  public List<T> findByExample(T entity); 

  /*************************************************************************** 
   * -------------------------Others ----------------------------------------* 
   **************************************************************************/ 

  /** 
   * 加锁指定的实使 
   * 
   * @param entity 
   * @param lockMode 
   */ 
  public void lock(T entity, LockMode lockMode); 

  /** 
   * 强制立即更新缓冲数据到数据库(否则仅在事务提交时才更新) 
   */ 
  public void flush(); 

  /** 
   * 清空缓存 
   * 
   * void 
   */ 
  public void clear(); 

  /*************************************************************************** 
   * --------------------------------相关知识炿--------------------------------* 
   * 
   * 1、Session的load方法和get方法都是通过给定的ID从数据库中加载一个持久化的对象?但两个斿* 
   * 法的区别在于:当数据库不存在于ID对应的记录时,load()方法抛出异常,迌get()方法返回null* 
   ***************************************************************************/ 

} 

//通用Hibernate DAO实现: 

package com.baiyyy.util.dao; 

/** 
* @filename:BaseHibernateDAO.java 
*/ 

import java.io.Serializable; 
import java.util.Collection; 
import java.util.Iterator; 
import java.util.List; 

import org.hibernate.Criteria; 
import org.hibernate.LockMode; 
import org.hibernate.Query; 
import org.hibernate.Session; 
import org.hibernate.criterion.Criterion; 
import org.hibernate.criterion.DetachedCriteria; 
import org.hibernate.criterion.Example; 
import org.hibernate.criterion.MatchMode; 
import org.hibernate.criterion.Projections; 

import com.baiyyy.workflow.pojo.TWfPackage; 

/** 
* 用Hibernate实现通用DAO接口 
* 
* @author yongtree 
* @date 2008-3-10 
* @param <T> 
* @param <ID> 
*/ 
public class BaseHibernateDAO<T, ID extends Serializable> implements 
    IBaseDAO<T, ID> { 
  // 保持实体对象类的类型 
  private Class<T> persistentClass; 

  private Session session; 

  /** 
   * 构?方泿 
   */ 
  @SuppressWarnings("unchecked") 
  public BaseHibernateDAO() { 
    //下面这种方式丿直有错误,不能得到真正的T.class,迌是Object.class 
    // this.persistentClass=GenericsUtils.getSuperClassGenricType(getClass()); 
    // System.out.println(obj.getClass().getName()); 
  } 

  @SuppressWarnings("unchecked") 
  public BaseHibernateDAO(Class clazz) { 
    this.persistentClass = clazz; 
  } 

  /** 
   * @param session 
   *            the session to set 
   */ 
  public void setSession(Session session) { 
    this.session = session; 
  } 

  /** 
   * 得到当前线程的Session对象的实便 
   * 
   * @return 
   */ 
  protected Session getSession() { 
    System.out.println("get session"); 
    return HibernateUtil.getCurrentSession(); 
  } 

  /** 
   * 得到持久化对象的类型 
   * 
   * @return 持久化类的类垿 
   */ 
  protected Class<T> getPersistentClass() { 
    return persistentClass; 
  } 

  @SuppressWarnings("unchecked") 
  public T findById(ID id, LockMode lock) { 
    // TODO Auto-generated method stub 
    T entity = (T) getSession().get(getPersistentClass(), id, lock); 
    if (entity != null) { 
      this.flush(); 
    } 

    return entity; 
  } 

  @SuppressWarnings("unchecked") 
  public T findById(Class c, ID id) { 
    // TODO Auto-generated method stub 
    T entity; 

    entity = (T) getSession().get(c, id); 

    return entity; 
  } 

  @SuppressWarnings("unchecked") 
  public T findById(ID id) { 
    // TODO Auto-generated method stub 
    T entity = (T) getSession().get(getPersistentClass(), id); 

    return entity; 
  } 

  @SuppressWarnings("unchecked") 
  public T loadById(ID id) { 
    // TODO Auto-generated method stub 
    T entity = (T) getSession().load(getPersistentClass(), id); 
    return entity; 
  } 

  @SuppressWarnings("unchecked") 
  public T loadById(Class c, ID id) { 
    // TODO Auto-generated method stub 
    T entity = (T) getSession().load(c, id); 
    return entity; 
  } 

  @SuppressWarnings("unchecked") 
  public T loadById(ID id, LockMode lock) { 
    // TODO Auto-generated method stub 
    T entity = (T) getSession().load(getPersistentClass(), id, lock); 
    return entity; 
  } 

  @SuppressWarnings("unchecked") 
  public List<T> loadAll() { 
    List<T> list = getSession().createQuery( 
        "from " + getPersistentClass().getName()).list(); 
    return list; 
  } 

  public T saveEntity(T entity) { 
    // TODO Auto-generated method stub 

    getSession().save(entity); 
    this.flush(); 
    return entity; 
  } 

  public void updateEntity(T entity) { 
    // TODO Auto-generated method stub 
    getSession().saveOrUpdate(entity); 
    this.flush(); 
  } 

  /** 
   * 该实现类暂时没有实现更新加锁的操使 
   */ 
  public void updateEntity(T entity, LockMode lock) { 
    // TODO Auto-generated method stub 
    getSession().saveOrUpdate(entity); 
    this.flush(); 
  } 

  public void saveOrUpdateAll(Collection<T> entities) { 
    getSession().saveOrUpdate(entities); 
    this.flush(); 
  } 

  public void deleteEntity(T entity) { 
    // TODO Auto-generated method stub 
    getSession().delete(entity); 
    this.flush(); 
  } 

  /** 
   * 该实现没有实现加锁删除对象的操作,在spring的DAO实现中已经实玿 
   */ 
  public void deleteEntity(T entity, LockMode lock) { 
    // TODO Auto-generated method stub 
    getSession().delete(entity); 
    this.flush(); 
  } 

  public void deleteEntityById(ID id) { 
    this.deleteEntity(this.loadById(id)); 
    this.flush(); 
  } 

  // 该实现没有实现加锁的删除,在spring的dao中已经实现了 
  public void deleteEntityById(ID id, LockMode lock) { 
    this.deleteEntity(this.loadById(id)); 
    this.flush(); 
  } 

  public void deleteAll(Collection<T> entities) { 
    this.flush(); 
    getSession().delete(entities); 
  } 
  
  public void merge(T entity){ 
    getSession().merge(entity); 
    this.flush(); 
  } 

  @SuppressWarnings("unchecked") 
  public T getEntity(String hsql) { 
    T uniqueResult = (T) getSession().createQuery(hsql).uniqueResult(); 
    // TODO Auto-generated method stub 
    return uniqueResult; 
  } 

  @SuppressWarnings("unchecked") 
  public List<T> getEntities(String hsql) { 
    // TODO Auto-generated method stub 

    List list = getSession().createQuery(hsql).list(); 
    return list; 
  } 

  @SuppressWarnings("unchecked") 
  public List<T> getEntities(String hql, int start, int number, 
      Object[] values) { 
    // TODO Auto-generated method stub 
    Query query = getSession().createQuery(hql); 
    for (int i = 0; i < values.length; i++) { 
      query.setParameter(i, values[i]); 
    } 
    query.setFirstResult(start); 
    query.setMaxResults(number); 
    List list = query.list(); 
    return list; 
  } 

  @SuppressWarnings("unchecked") 
  public List<T> getEntities(String hql, int start, int number) { 
    // TODO Auto-generated method stub 
    Query query = getSession().createQuery(hql); 
    query.setFirstResult(start); 
    query.setMaxResults(number); 
    List list = query.list(); 
    return list; 
  } 

  @SuppressWarnings("unchecked") 
  public List<T> getEntities(String hql, Object[] values) { 
    // TODO Auto-generated method stub 
    Query query = getSession().createQuery(hql); 
    for (int i = 0; i < values.length; i++) { 
      query.setParameter(i, values[i]); 
    } 
    return query.list(); 
  } 

  @SuppressWarnings("unchecked") 
  public List<T> findByNamedQuery(String queryName) { 
    // TODO Auto-generated method stub 
    return getSession().getNamedQuery(queryName).list(); 
  } 

  @SuppressWarnings("unchecked") 
  public List<T> findByNamedQuery(String queryName, Object[] values) { 
    // TODO Auto-generated method stub 
    Query query = getSession().getNamedQuery(queryName); 
    for (int i = 0; i < values.length; i++) { 
      query.setParameter(i, values); 
    } 
    return query.list(); 
  } 

  /** 
   * 注意:该方法是?过设置参数来进行命名查询,承以在传参数时,一定要注意paramNames和values的长度,位置要一丿对应? 
   */ 
  @SuppressWarnings("unchecked") 
  public List<T> findByNamedQuery(String queryName, String[] paramNames, 
      Object[] values) { 
    // TODO Auto-generated method stub 
    Query query = getSession().getNamedQuery(queryName); 
    for (int i = 0; i < paramNames.length; i++) { 
      query.setParameter(paramNames[i], values[i]); 
    } 
    return query.list(); 
  } 

  @SuppressWarnings("unchecked") 
  public Iterator<T> iterate(String hql) { 
    // TODO Auto-generated method stub 
    return getSession().createQuery(hql).iterate(); 
  } 

  @SuppressWarnings("unchecked") 
  public Iterator<T> iterate(String hql, Object[] values) { 
    // TODO Auto-generated method stub 
    Query query = getSession().createQuery(hql); 
    for (int i = 0; i < values.length; i++) { 
      query.setParameter(i, values[i]); 
    } 
    return query.iterate(); 
  } 

  public DetachedCriteria createDetachedCriteria() { 
    // TODO Auto-generated method stub 
    return DetachedCriteria.forClass(this.persistentClass); 
  } 

  public Criteria createCriteria() { 
    // TODO Auto-generated method stub 
    return this.createDetachedCriteria().getExecutableCriteria( 
        this.getSession()); 
  } 

  /** 
   * 该方法没有经过验证,不能保证正确,在spring的实现中已经实现亿 
   */ 
  @SuppressWarnings("unchecked") 
  public List<T> findByCriteria(DetachedCriteria criteria) { 
    // TODO Auto-generated method stub 
    return criteria.getExecutableCriteria(this.getSession()).list(); 
  } 

  @SuppressWarnings("unchecked") 
  public List<T> findByCriteria(DetachedCriteria criteria, int firstResult, 
      int maxResults) { 
    // TODO Auto-generated method stub 
    return criteria.getExecutableCriteria(this.getSession()) 
        .setFirstResult(firstResult).setMaxResults(maxResults).list(); 

  } 

  /** 
   * 动濁查诿 
   * 
   * @param criterion 
   * @return 
   */ 
  public @SuppressWarnings("unchecked") 
  List<T> findByCriteria(Criterion... criterion) { 
    Criteria crit = getSession().createCriteria(getPersistentClass()); 
    for (Criterion c : criterion) { 

      if (c != null) { 

        crit.add(c); 

      } 
    } 
    List list = crit.list(); 
    return list; 
  } 

  @SuppressWarnings("unchecked") 
  public Integer getRowCount(DetachedCriteria criteria) { 
    // TODO Auto-generated method stub 
    criteria.setProjection(Projections.rowCount()); 
    List list = this.findByCriteria(criteria, 0, 1); 
    return (Integer) list.get(0); 

  } 

  @SuppressWarnings("unchecked") 
  public Object getStatValue(DetachedCriteria criteria, String propertyName, 
      String StatName) { 
    // TODO Auto-generated method stub 
    if (StatName.toLowerCase().equals("max")) 
      criteria.setProjection(Projections.max(propertyName)); 
    else if (StatName.toLowerCase().equals("min")) 
      criteria.setProjection(Projections.min(propertyName)); 
    else if (StatName.toLowerCase().equals("avg")) 
      criteria.setProjection(Projections.avg(propertyName)); 
    else if (StatName.toLowerCase().equals("sum")) 
      criteria.setProjection(Projections.sum(propertyName)); 
    else 
      return null; 
    List list = this.findByCriteria(criteria, 0, 1); 
    return list.get(0); 
  } 

  @SuppressWarnings("unchecked") 
  public List<T> findByExample(T exampleInstance) { 
    // TODO Auto-generated method stub 
    Criteria crit = getSession().createCriteria(getPersistentClass()); 
    Example example = Example.create(exampleInstance); 
    example.ignoreCase().enableLike(MatchMode.ANYWHERE);// 忽略大小写,并进行模糊比辿 
    example.excludeZeroes();// 对于属濧中有数字类型的,如果exampleInstance的属性忼为0,就把它添加到查询中 
    crit.add(example); 
    return crit.list(); 

  } 

  public void lock(T entity, LockMode lockMode) { 
    // TODO Auto-generated method stub 
    getSession().lock(entity, lockMode); 
  } 

  public void flush() { 
    // TODO Auto-generated method stub 
    getSession().flush(); 
  } 

  public void clear() { 
    // TODO Auto-generated method stub 
    getSession().clear(); 
  } 

} 


总结:这一章节主要讨论一下什么时候使用泛型。


这一章节就到这里,谢谢。

-----------------------------------

目录



  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值