了解泛型、反射、单例模式的请进。

codeartisan 2008-01-26 06:58:24
先贴上写好了的代码,问题在代码后面。
是一个简单的BeanUtil,具体的功能是复制VO的属性值到PO,如果VO的属性值为null则不复制。

package net.javayuan.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
* @(#)VO2PO.java Jan 23, 2008 9:00:55 AM
*
* @author Yuan
* VO到PO的属性复制工具
*/
public class VO2PO {

private static final VO2PO INSTANCE = new VO2PO();

private VO2PO(){
//
}

public static VO2PO getInstance(){
return INSTANCE;
}

/**
* 复制属性
* @param vo 源对象
* @param po 目标对象
* */
public void copyProperties(Object vo, Object po){

Class<?> voClass = vo.getClass();
Class<?> poClass = po.getClass();

Method[] methods = voClass.getDeclaredMethods();

for (Method method : methods){
String methodName = method.getName();
String fieldName = "";
String setterName = "";

if (methodName.startsWith("get")){
fieldName = methodName.substring(3,4).toLowerCase() + methodName.substring(4);
setterName = "set" + methodName.substring(3);
}

if (methodName.startsWith("is")){
fieldName = methodName.substring(2,3).toLowerCase() + methodName.substring(3);
setterName = "set" + methodName.substring(2);
}

if (!"".equals(fieldName)){
try {
Object o = method.invoke(vo, new Object[]{});
if (o != null){
Class<?> fieldType = poClass.getDeclaredField(fieldName).getType();
Method setter = poClass.getDeclaredMethod(setterName, fieldType);
setter.invoke(po, o);
}
} catch (IllegalArgumentException ex) {
ex.printStackTrace();
} catch (SecurityException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
} catch (InvocationTargetException ex) {
ex.printStackTrace();
} catch (NoSuchMethodException ex) {
ex.printStackTrace();
} catch (NoSuchFieldException ex) {
ex.printStackTrace();
}
}
}
}
public static void main(String[] args){
Bean bean1 = new Bean();
bean1.setBooleanValue(true);
bean1.setStringValue(null);
bean1.setIntValue(321);

Bean bean2 = new Bean();
bean2.setBooleanValue(false);
bean2.setStringValue("bean2");
bean2.setIntValue(123);

VO2PO.getInstance().copyProperties(bean1, bean2);

System.out.println(bean2.getIntValue());
System.out.println(bean2.getStringValue());
System.out.println(bean2.isBooleanValue());
}
}

class Bean{

private int intValue;
private String stringValue;
private boolean booleanValue;

public int getIntValue() {
return intValue;
}

public void setIntValue(int intValue) {
this.intValue = intValue;
}

public String getStringValue() {
return stringValue;
}

public void setStringValue(String stringValue) {
this.stringValue = stringValue;
}

public boolean isBooleanValue() {
return booleanValue;
}

public void setBooleanValue(boolean booleanValue) {
this.booleanValue = booleanValue;
}
}


第一个问题:是否所有用到Object做参数的地方都可以(或者有必要)写成泛型?
第二个问题:如果第一个问题的答案为true,我想把这个VO2PO类改写成泛型的VO2PO <V,P> ,该怎么改?
第三个问题:类似这样的工具类,你一般是如何设计?单例?静态方法类?还是一般的类?为什么?
...全文
244 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
第二个问题:改用泛型参数加以限制。

public static <V, P extends V> void aMethod(V vo, P po);
caiming250 2008-01-26
  • 打赏
  • 举报
回复
1 ture
2 个人理解: 对于单体模式 我们是不能运用 范型类的 因为:范型是一个编译器行为.
如果 编译时 我们在单体模式上面可以使用范型类 我们就可以声明各种范型的单体(如:VO2PO<Bean,Bean>的单体 和 VO2PO<OtherBean,Bean> 的单体 注意: 这两个单体是是两个对象)
可是 在运行时 我们只能够让VO2PO 存在一个单体 也就是一个VO2PO对象 这与编译时的两个VO2PO对象发生了冲突 所以不能对单体模式使用范型
3 如果真如我理解的 对于单体模式我们没有办法使用范型类 就只有这样: 将对范型的支持丢到方法上面 把你的copyProperties 方法声明成范型方法



/**
* Object1 和 Object2 分别是你的V 父类 和P父类
*/
public <V extends Object1,P extends Object2> void copyProperties(V vo, P po){

//action......

}

wddaff2008 2008-01-26
  • 打赏
  • 举报
回复
uuuuuuuuuuuuuuuuuuuuuuuuuu
  • 打赏
  • 举报
回复
对于这个程序而言,我认为有些地方可以改进一下:
1,Introspector.getBeanInfo(Class);获得BeanInfo实例;
2,beanInfo.getPropertyDescriptors();获得Bean中所有的PropertyDescriptor,即属性描述;
3,PropertyDescriptor中有getReadMethod()和getWriteMethod()方法取得Bean的set/get的Method;
4,再通过Method进行操作。

复制整个属性,必须保证第一个参数与第二参数是同一种类型,或者是第一参数是第二个参数的父类,第二个参数只能是子类。如果第二个参数是父类,而第一个参数是子类可能造成复制失败,我认为应该采用泛型进行约束。

第三个问题,我认为应采用静态方法且将构造置为private(不允许产生实例),主要是由于工具类无须与其他的类进行交互,或者与其他的类毫无关系,可以在任何时候、任何状态下进行操作,工具类是没有必要产生实例的,比如:JDK中的System、Math、Arrays等等。
cangyue87 2008-01-26
  • 打赏
  • 举报
回复
为什么又是竹子的1楼....

我已经连续3天揭不开锅了....
老紫竹 2008-01-26
  • 打赏
  • 举报
回复
1 是的,至少我还没遇到不能的,泛型主要是增加编译期间的检查。
2 有一些通用类,不能加泛型,不如JSP里面的session, 我们无法预期里面保存什么,而且也不能那样做,所以最终是Object。和没写是一样的。
3 至于是否能单例。我的理解,如果都是方法,不涉及到类一级的属性,则可以。 也就是无状态的类。 每个访问对类来说都是全新的。

waterborn 2008-01-26
  • 打赏
  • 举报
回复
没仔细看. 我复制非NULL值的属性到dest Bean 是这么做的
用了apache 的BeanUtil.jar

public static void copyBeanNotNullProperty(Object dest, Object orig) throws IllegalAccessException,
InvocationTargetException {
// Validate existence of the specified beans
if (dest == null) {
throw new IllegalArgumentException("No destination bean specified");
}
if (orig == null) {
throw new IllegalArgumentException("No origin bean specified");
}
if (orig instanceof Map) {
throw new IllegalArgumentException("No support map");
}

/* if (orig is a standard JavaBean) */
PropertyDescriptor origDescriptors[] = PropertyUtils.getPropertyDescriptors(orig);
for (int i = 0; i < origDescriptors.length; i++) {
String name = origDescriptors[i].getName();
if ("class".equals(name)) {
continue; // No point in trying to set an object's class
}
if (PropertyUtils.isReadable(orig, name) && PropertyUtils.isWriteable(dest, name)) {
try {
Object value = PropertyUtils.getSimpleProperty(orig, name);
if (value != null) {
BeanUtils.copyProperty(dest, name, value);
}
} catch (NoSuchMethodException e) {
}
}
}

}

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧