Java反映2个对象

时间:2009-12-23 02:45:49

标签: java reflection

嗨,我收到了以下代码:

ModuleA.Student student 1 = null;
ModuleB.Student student 2 = null;

student2 = retrieveStudentFacade().findStudentbyName("John");
student1 = StudentSessionEJBBean.convert(student2,ModuleA.Student.Class);

问题现在是student1.getId();返回null但应该返回一个值。下面是转换器方法,有人指导我使用这种方法来反映对象。它工作得很好,因为没有错误发生只是没有值返回?

更新

   public static <A,B> B convert(A instance, Class<B> targetClass) throws Exception {
B target = (B) targetClass.newInstance();
for (Field targetField: targetClass.getDeclaredFields()) {
    Field field = instance.getClass().getDeclaredField(targetField.getName());
    field.setAccessible(true);
    targetField.set(target, field.get(instance));
}
return target;
}

4 个答案:

答案 0 :(得分:2)

真的,真的,你真的不想这样做!那么你可能想要这样做......但你真的真的不应该这样做。

而不是使用反射来使用语言并提供这样的构造函数:

package ModuleA;  // should be all lower case by convention...

public class Student
{
    // pick differnt names for them is a good idea... 2 classes called Student is asking for trouble
    public Student(final ModualB.Student other)
    {
        // do the copying here like xxx =  other.getXXX();
    }
}

您的代码中要解决的问题:

  • 不要声明方法“抛出异常”,因为你必须有“catch(Exception ex)”,这可能会导致你在代码中隐藏错误。

  • (猜测)至少在catch块中执行“ex.printStackTrace()”(或记录它),以便查看是否出现了问题。

答案 1 :(得分:1)

你确定你没有吞下任何异常吗?

我建议您使用setter / getter方法,而不是直接访问字段。您可以类似于字段提取方法,然后在对象上调用它们。

虽然代码变得复杂,但您应该能够实现您想要的目标。

像bean copy utils这样的工具也使用getter / setter(这就是为什么它们只适用于“bean”,它们具有符合命名约定的getter / setter)。

答案 2 :(得分:1)

你要做的事情背后的原因很奇怪(分享它们),但有比手动使用反射更好的方法。

  1. Apache commons-beanutils BeanUtils.copyProperties(source, target)
  2. Spring BeanUtils.copyProperties(source, target)
  3. 但是你需要公共的setter / getter来处理你想要复制的属性(你应该拥有它们),并且你必须事先创建目标对象的实例。

答案 3 :(得分:0)

getFields方法只返回可公开访问的字段(即不是私有,受保护或可以访问包。来自JavaDoc:

  

返回一个包含Field个对象的数组,这些对象反映了类或接口的所有可访问的公共字段

我假设你关心的id字段是私有的,所以你应该使用getDeclaredFields方法。

  

返回Field个对象的数组,这些对象反映由此Class对象表示的类或接口声明的所有字段。这包括公共,受保护,默认(包)访问和私有字段,但不包括继承的字段。

要反射设置从此方法返回的(私有)字段,您还需要调用field.setAccessible(true)。