泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率;
泛型的用法核心:实质是将具有重复逻辑或者类似功能类集合进行逻辑块的抽取,具体办法是创建一个包装类,将该集合的类作为该类中的一个属性或者暴露一个获取的接口方法,而这个类的属性的类型是自定义的,而包装类中的逻辑块即为该类集合所共有逻辑。注意,若要使用该集合类所具有的方法,无论集合中的类是以属性还是接口的形式提供,都是要在实例化改包装类的时候要初始化。需要提供对应的初始化方法,若该类为包装类属性,则提供构造函数,若为接口方法,则包装类的该方法为虚方法,且包装类为虚函数。以便使用的时候可以自定义初始化。
下述例子即为接口实例化泛型类对象的例子
public abstract class AbstractCommonQuartzJob<T extends IQuartzCommonSIDSV> implements Job {
private static Logger logger = LoggerFactory.getLogger(AbstractCommonQuartzJob.class);
/**
* 获取执行日志;
* @return
*
*/
abstract protected Logger getLogger();
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
JobDataMap jobDataMap = null;
String provinceCode = null ;
Map<String,String> extendParams = new java.util.HashMap<>();
if(context == null){
} else {
jobDataMap = context.getJobDetail().getJobDataMap();
//获取设置的省分编码;
provinceCode = jobDataMap.getString(JobConstants.JobParam_ProvinceCode);
for(String key : jobDataMap.keySet()){
if( jobDataMap.get(key) != null){
extendParams.put(key,jobDataMap.getString(key));
}
}
}
IQuartzCommonSIDSV sv = this.getService();
try{
if(StringUtils.isEmpty(provinceCode)){
this.getLogger().info("定时任务开始,获取的省分编码为空,执行所有省分处理");
sv.dealQuartz(extendParams);
} else {
this.getLogger().info("定时任务开始,获取的省分编码列表为:"+provinceCode);
String[] provinceCodes = provinceCode.split(JobConstants.JobParam_SPLIT);
sv.dealQuartzByProvinceCodes(provinceCodes,extendParams);
}
} catch(Exception e){
this.getLogger().error("定时任务失败!", e);
throw new JobExecutionException(e);
} finally {
this.getLogger().info("定时任务结束!");
}
}
/**
* 获取 对应的服务;
* @return
*
*/
abstract protected T getService();
}
还有一种泛型使用场景是方法泛型,此类泛型的运用目的往往在于对各种对象的格式转换或者加工,使用泛型可以避免传入对象的限制。
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import org.apache.commons.beanutils.BeanUtils;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
public class BeanUtil {
/**
* 把实体bean对象转换成DBObject
* @param bean
* @return
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
public static <T> DBObject bean2DBObject(T bean) throws IllegalArgumentException,
IllegalAccessException {
if (bean == null) {
return null;
}
DBObject dbObject = new BasicDBObject();
// 获取对象对应类中的所有属性域
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
// 获取属性名
String varName = field.getName();
// 修改访问控制权限
boolean accessFlag = field.isAccessible();
if (!accessFlag) {
field.setAccessible(true);
}
Object param = field.get(bean);
if (param == null) {
continue;
} else if (param instanceof Integer) {//判断变量的类型
int value = ((Integer) param).intValue();
dbObject.put(varName, value);
} else if (param instanceof String) {
String value = (String) param;
dbObject.put(varName, value);
} else if (param instanceof Double) {
double value = ((Double) param).doubleValue();
dbObject.put(varName, value);
} else if (param instanceof Float) {
float value = ((Float) param).floatValue();
dbObject.put(varName, value);
} else if (param instanceof Long) {
long value = ((Long) param).longValue();
dbObject.put(varName, value);
} else if (param instanceof Boolean) {
boolean value = ((Boolean) param).booleanValue();
dbObject.put(varName, value);
} else if (param instanceof Date) {
Date value = (Date) param;
dbObject.put(varName, value);
}
// 恢复访问控制权限
field.setAccessible(accessFlag);
}
return dbObject;
}
/**
* 把DBObject转换成bean对象
* @param dbObject
* @param bean
* @return
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
public static <T> T dbObject2Bean(DBObject dbObject, T bean) throws IllegalAccessException,
InvocationTargetException, NoSuchMethodException {
if (bean == null) {
return null;
}
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
String varName = field.getName();
Object object = dbObject.get(varName);
if (object != null) {
BeanUtils.setProperty(bean, varName, object);
}
}
return bean;
}
}