從頭認識java-13.7 什麼時候使用泛型?
這一章節我們來討論一下什麼時候使用泛型?
答案:當你希望代碼能夠跨多個類型(不同的類型,不包含繼承關係)工作的時候。
1.當沒有確切類型的時候
下面是錯誤的代碼:
package com.ray.ch13;public class Test {private T obj;public Test(T t) {obj = t;}public void test() {// obj.f();//error}}
從上面的代碼可以看出,在沒有確切類型的時候,obj是不能調用任何方法。
正確的代碼:
package com.ray.ch13;public class Test {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 {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 {@Overridepublic 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; /** * 承有業務資料的基礎提供者 *
* 承有CRUD (建立,讀取,修改和刪陿)基本資料的操作在這個介面中都是獨立的_ 並且承有的DAO都可以使用這些基本實玿 * * @author yongtree * * @date:2008-03-04 */ public interface IBaseDAO { /*************************************************************************** * -------------------基本棿索?增加?修改?刪除操使---------------------------- * **************************************************************************/ // --------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 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 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 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 getEntities(String hsql); /** * 使用帶參數的HQL語句進行查詢 * * @param hsql * @param obj * @return */ public List getEntities(String hsql, Object[] values); public List getEntities(String hql, int start, int number); public List getEntities(String hql, int start, int number, Object[] values); /** * 使用命名的HQL語句棿索數捿 * * @param queryName * @return */ public List findByNamedQuery(String queryName); /** * 使用帶參數的命名HSQL語句棿索數捿 * * @param queryName * @param values * @return */ public List findByNamedQuery(String queryName, Object[] values); /** * 使用帶具名引數的命名HSQL語句棿索數捿 * * @param queryName * @param paramNames * @param values * @return */ public List findByNamedQuery(String queryName, String[] paramNames, Object[] values); /** * 使用HQL語句棿索資料,返回 Iterator * * @param queryString * @return */ public Iterator iterate(String queryString); /** * 使用帶參數HSQL語句棿索資料,返回 Iterator * * @param queryString * @param values * @return */ public Iterator iterate(String queryString, Object[] values); /*************************************************************************** * -----------------------------Criteria動濁查諉---------------------------- * **************************************************************************/ /** * 建立與會話無關的棿索標準對豿 */ public DetachedCriteria createDetachedCriteria(); /** * 建立與會話綁定的棿索標準對豿 * * @return */ public Criteria createCriteria(); /** * 使用指定的檢索標準檢索數捿 * * @param criteria * @return */ public List findByCriteria(DetachedCriteria criteria); /** * 使用指定的檢索標準檢索資料,返回部分記錄 * * @param criteria * @param firstResult * @param maxResults * @return */ public List findByCriteria(DetachedCriteria criteria, int firstResult, int maxResults); /** * 通過動濁查詢條件進行查諉 * * @param criterion * @return List */ @SuppressWarnings("unchecked") public List 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 */ public List 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 * @param */ public class BaseHibernateDAO implements IBaseDAO { // 保持實體物件類的類型 private Class 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 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 loadAll() { List 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 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 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 getEntities(String hsql) { // TODO Auto-generated method stub List list = getSession().createQuery(hsql).list(); return list; } @SuppressWarnings("unchecked") public List 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 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 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 findByNamedQuery(String queryName) { // TODO Auto-generated method stub return getSession().getNamedQuery(queryName).list(); } @SuppressWarnings("unchecked") public List 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 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 iterate(String hql) { // TODO Auto-generated method stub return getSession().createQuery(hql).iterate(); } @SuppressWarnings("unchecked") public Iterator 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 findByCriteria(DetachedCriteria criteria) { // TODO Auto-generated method stub return criteria.getExecutableCriteria(this.getSession()).list(); } @SuppressWarnings("unchecked") public List 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 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 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(); } }
總結:這一章節主要討論一下什麼時候使用泛型。