`

Java泛型

    博客分类:
  • Java
 
阅读更多
泛型


泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

  Java语言引入泛型的好处是安全简单。

  在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,

而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常

,这是一个安全隐患。

  泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。

  泛型在使用中还有一些规则和限制:

  1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型。

  2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。

  3、泛型的类型参数可以有多个。

  4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上成为“有界类型”。

  5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName(java.lang.String);

  泛型还有接口、方法等等,内容很多,需要花费一番功夫才能理解掌握并熟练应用。在此给出我曾经了解泛型时候写出的两个例子(根据看的印象写的),

实现同样的功能,一个使用了泛型,一个没有使用,通过对比,可以很快学会泛型的应用,学会这个基本上学会了泛型70%的内容。

  例子一:使用了泛型


Java code

public class Gen<T> {
 private T ob; //定义泛型成员变量

 public Gen(T ob) {
  this.ob = ob;
 }

 public T getOb() {
  return ob;
 }

 public void setOb(T ob) {
  this.ob = ob;
 }

 public void showTyep() {
  System.out.println("T的实际类型是: " + ob.getClass().getName());
 }
}

public class GenDemo {
 public static void main(String[] args){
 //定义泛型类Gen的一个Integer版本
 Gen<Integer> intOb=new Gen<Integer>(88);
 intOb.showTyep();
 int i= intOb.getOb();
 System.out.println("value= " + i);

 System.out.println("----------------------------------");

 //定义泛型类Gen的一个String版本
 Gen<String> strOb=new Gen<String>("Hello Gen!");
 strOb.showTyep();
 String s=strOb.getOb();
 System.out.println("value= " + s);
}
}



例子二:没有使用泛型

Java code

public class Gen2 {
 private Object ob; //定义一个通用类型成员

 public Gen2(Object ob) {
  this.ob = ob;
 }

 public Object getOb() {
  return ob;
 }

 public void setOb(Object ob) {
  this.ob = ob;
 }

 public void showTyep() {
  System.out.println("T的实际类型是: " + ob.getClass().getName());
 }
}

public class GenDemo2 {
 public static void main(String[] args) {
  //定义类Gen2的一个Integer版本
  Gen2 intOb = new Gen2(new Integer(88));
  intOb.showTyep();
  int i = (Integer) intOb.getOb();
  System.out.println("value= " + i);

  System.out.println("----------------------------------");

  //定义类Gen2的一个String版本
  Gen2 strOb = new Gen2("Hello Gen!");
  strOb.showTyep();
  String s = (String) strOb.getOb();
  System.out.println("value= " + s);
 }
}


运行结果:

  两个例子运行Demo结果是相同的,控制台输出结果如下:

  T的实际类型是:

Java code

java.lang.Integer
value= 88
----------------------------------
T的实际类型是: java.lang.String
value= Hello Gen!

Process finished with exit code 0


((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]

http://blog.sina.com.cn/s/blog_63db5fc10100tu7t.html

getClass().getGenericSuperclass()返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type 然后将其转换ParameterizedType。 getActualTypeArguments()返回表示此类型实际类型参数的 Type 对象的数组。 [0]就是这个数组中第一个了。 简而言之就是获得超类的泛型参数的实际类型。


import java.lang.reflect.Type;
import java.lang.reflect.ParameterizedType;

public class GenericDao<T> {

private Class entityClass;
protected GenericDao(){
Type type = getClass().getGenericSuperclass();
Type trueType = ((ParameterizedType)type).getActualTypeArguments()[0];
this.entityClass = (Class) trueType;
}

public void outputResult(){

System.out.print("Test Dao Result: "+entityClass.getName());
}
}


import com.api.BuildServiceAsync;
import com.comm.GenericDao;

public class OptionManager extends GenericDao<BuildServiceAsync>{

public OptionManager(){
super();
}

}



public interface BuildServiceAsync {

void testInterface1();

void testInterface2();

}


public class OptionTest {

public static void main (String[] args){



OptionManager manager = new OptionManager();
        
manager.outputResult();

}
}



<T, ID extends Serializable>

http://www.iteye.com/problems/38389

http://www.blogjava.net/jelver/articles/344686.html

http://szqiqi1.blog.163.com/blog/static/9942537620106242435938/

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.support.JpaDaoSupport;
import org.springframework.util.Assert;

public class GenericDao<T, ID extends Serializable> extends JpaDaoSupport {

private Class<T> entityClass;
private final Log log = new Log(ModuleLogEnum.JAVA_COMMON, this.getClass());

@SuppressWarnings("unchecked")
public GenericDao() {
this.entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}

public T findById(ID id) throws ObjectRetrievalFailureException {
Assert.notNull(id);
return getJpaTemplate().find(entityClass, id);
}

@SuppressWarnings("unchecked")
public List<T> findAll() {
final String queryString = "select model from " + entityClass.getSimpleName() + " model";
return getJpaTemplate().find(queryString);

}

public List<T> findByProperty(String propertyName, final Object value) {
final String queryString = "select model from " + entityClass.getSimpleName() + " model where model." + propertyName + "= ?";
return findByQueryString(queryString, value);
}

}



import org.springframework.stereotype.Component;
@Component
public class AutomationDeviceDao extends GenericDao<AutomationDevice, Integer> {

// Constructor required because of the Exception
public AutomationDeviceDao() throws Exception {
super();
}

}


import java.util.ArrayList;
import java.util.List;
import org.springframework.util.CollectionUtils;
public abstract class GenericService<TDto extends GenericElementDto, TDb, TDao extends GenericDao<TDb, Integer>> implements GenericIService<TDto> {
private TDao dao; // Stores the Dao
private final Log logger = new Log(ModuleLogEnum.JAVA_COMMON, this.getClass());

/**
* Converts a Model object into a Dto Object
* @param iElement model object
* @return TDto object
* @throws Exception
*/
public abstract TDto createDtoFromModel(TDb iElement) throws Exception;

/**
* Converts a Dto object into a database Object
* @param iElementDto object
* @return TDb database object
*/
public abstract TDb createModelFromDto(TDto iElementDto) throws Exception;

/**
* Create a basic database object from only the Id (for operations like delete)
* @param iElementId Id of the object to be created
* @return TDb database object
*/
public abstract TDb createModelFromId(Integer iElementId) throws Exception;

}


@Transactional
@Service("automationDeviceService")
public class AutomationDeviceService extends GenericService<AutomationDeviceDto, AutomationDevice, AutomationDeviceDao> implements IAutomationDeviceService {

@Autowired
private IAutomationSetupService automationSetupService;
@Autowired
private AutomationDeviceDao automationDeviceDao;

@Override
public AutomationDeviceDto searchById(Integer iElementId) throws Exception {
super.setDao(automationDeviceDao);
return super.searchById(iElementId);
}
}


@Override
public AutomationDeviceDto update(AutomationDeviceDto iElementDto) throws Exception {
super.setDao(automationDeviceDao);
checkDeviceSubtype(iElementDto);
return super.update(iElementDto);
}

}


Dao层中基本操作的复用,和Spring配置中的一些代码复用


简明的说一下类的作用:



BaseDao(接口类):

实体中共有的增删改查操作的接口



BaseHibernateDao(实现类):继承HibernateDaoSupport,实现BaseDao接口

实现BaseDao类中的基本操作。



UserDao(接口类):继承BaseDao类

实体中除了基本操作的额外操作,用于扩充功能。



UserHibernateDao(实现类):继承BaseHibernateDao类,实现UserDao接口

实现UserDao类的操作。





从上面的分析可以看出来,UserDao类是包含有全部的底层操作的接口,而UserHibernateDao类是实现了UserDao

类的全部操作。实现了base类后,实际上是简化了实体通用的操作,只写一次就行了。。

在ssh2 结构中,可以利用spring 对UserService 类进行注入UserDao类即可。如Spring的配置文件:

<bean id="daoTemplate" abstract="true">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<bean id="userDao" class="dao.hibernate.UserHibernateDao" parent="daoTemplate"/>
<bean id="userService" class="service.imp.UserService">
<property name="userDao" ref="userDao"/>
<bean id="***Dao" class="dao.hibernate.***HibernateDao" parent="daoTemplate"/>
<bean id="***Service" class="service.imp.UserService">
<property name="***Dao" ref="***Dao"/>

从这个配置文件上又有个 daoTemplate 的bean ,这个bean 是一个抽象类,注入了sessionFactory,如果其他bean类继承它的话,就可以不用在为它注入sessionFactory了,,这个也是一个技巧,有点像Base类,功能都是实现代码的复用。。。

下面是上面一些类的演示代码:

BaseDao

import java.io.Serializable;
import java.util.List;
public interface BaseDao<T,ID extends Serializable> {
public void save(T entity);
public void delete(T entity);
public void deleteById(Class<T> entityClass,ID id);
public void update(T entity);
public T findById(Class<T> entityClass,ID id);
public List<T> findAll(Class<T> entityClass);
}

BaseHibernateDao
package dao.base;
import java.io.Serializable;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
public class BaseHibernateDao<T,ID extends Serializable> extends HibernateDaoSupport implements BaseDao<T,ID> {
@Override
public void delete(T entity) {
this.getHibernateTemplate().delete(entity);
}
@Override
public void deleteById(Class<T> entityClass, ID id) {
delete(this.findById(entityClass, id));
}
@Override
public T findById(Class<T> entityClass, ID id) {
return (T)this.getHibernateTemplate().get(entityClass, id);
}
@Override
public List<T> findAll(Class<T> entityClass) {
String name=entityClass.getName();
return this.getHibernateTemplate().find("from"+name);
}
@Override
public void save(T entity) {
this.getHibernateTemplate().save(entity);
}
@Override
public void update(T entity) {
this.getHibernateTemplate().update(entity);
}
}


UserDao


package dao;
import dao.base.BaseDao;
import model.User;
public interface UserDao extends BaseDao<User,Integer>{
User findUserByNameAndPass(String name,String password);
}



UserHibernateDao

package dao.hibernate;  
  
import java.util.List;  
  
import model.User;  
import dao.UserDao;  
import dao.base.BaseHibernateDao;  
  
public class UserHibernateDao extends BaseHibernateDao<User,Integer> implements UserDao {  
  
    @Override  
    public User findUserByNameAndPass(String name, String password) {  
        // TODO Auto-generated method stub  
        List<User> us=this.getHibernateTemplate().find("from User user where name=? and password=?",new Object[]{name,password});  
        if(us.size()==1)  
            return us.get(0);  
        else  
            return null;  
    }  
  
}

分享到:
评论

相关推荐

    Java泛型编程指南.pdf

    Java泛型编程指南.pdf 此文章译自SUN的泛型编程指南

    Java泛型和集合

    Java Generics and Collections 英文版,详细描述java 泛型技术

    java 泛型类的类型识别示例

    java 泛型类的类型识别示例 java 泛型类的类型识别示例 java 泛型类的类型识别示例

    java 泛型接口示例

    java 泛型接口示例 java 泛型接口示例 java 泛型接口示例

    java 泛型方法使用示例

    java 泛型方法使用示例 java 泛型方法使用示例 java 泛型方法使用示例

    Java泛型的用法及T.class的获取过程解析

    主要介绍了Java泛型的用法及T.class的获取过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    JAVA泛型加减乘除

    这是一个使用JAVA实现的泛型编程,分为两部分,第一部分创建泛型类,并实例化泛型对象,得出相加结果。 第二部分用户自行输入0--4,选择要进行的加减乘除运算或退出,再输入要进行运算的两个数,并返回运算结果及...

    java泛型技术之发展

    java泛型技术之发展,学习JAVA 泛型的不错东东

    1.java泛型定义.zip

    1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1.java泛型定义.zip1....

    很好的Java泛型的总结

    很好的Java泛型的总结,看完之后你一定会知道java泛型的底层机制,你一定会学会Java泛型!

    4.java泛型的限制.zip

    4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip4.java泛型的限制.zip...

    java泛型学习ppt

    java,学习java泛型,java培训之泛型.pptxjava培训之泛型.pptxjava培训之泛型.pptxjava培训之泛型.pptx

    java泛型总结

    深入理解java泛型,包括类名泛型的定义,方法泛型定义,泛型的返回

    SUN公司Java泛型编程文档

    Sun公司的Java泛型编程文档,英文原版和网络翻译版,想对泛型有更清楚的认识的朋友可以看看,必定会有所帮助

    java泛型详解.pdf

    java泛型详解.pdf

    JAVA泛型简单排序实例

    JAVA泛型源代码实现以下功能:返回数组元素的最大值/最小值下标;判断数组元素是否按升序排列;T对象数组排序;二分法查找key元素;

    思维导图之Java泛型详解

    思维导图之Java泛型详解

    Java泛型技术之发展

    Java泛型技术之发展

    JAVA泛型教程(帮你解决学习泛型的苦恼)

    JAVA泛型教程(帮你解决学习泛型的苦恼). Java 泛型编程可能会碰到很多问题,本教程可能会对你有帮助哦。

Global site tag (gtag.js) - Google Analytics