views:

131

answers:

4

Hi i got the code below :

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

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

The problem now student1.getId(); return null but supposed to return me a value. Below is the converter method, someone guide me using this method to reflect the objects. It works nice as no error occur just no value return?

UPDATE

   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;
}
A: 

The getFields method only returns publicly-accessible fields (i.e. not private, protected, or package-accessible. From the JavaDoc:

Returns an array containing Field objects reflecting all the accessible public fields of the class or interface

I assume that the id field you care about is private, so you should instead use the getDeclaredFields method.

Returns an array of Field objects reflecting all the fields declared by the class or interface represented by this Class object. This includes public, protected, default (package) access, and private fields, but excludes inherited fields.

To reflectively set the (private) fields returned from this method, you will also need to call field.setAccessible(true).

Brett Daniel
hi my ModuleB.Student the attributes is private ModuleA.Student is actually a proxy is protected
+1  A: 

Are you sure you are not swallowing any Exceptions??

I suggest you use the setter/getter methods instead of accessing the fields directly. You can extract methods similarly to fields, and then invoke them on the objects.

Although code becomes complicated, you should be able to achieve what you want.

Tools like bean copy utils also use getter/setter (that's why they work only on "beans", which have getter/setters that conform to the naming conventions).

Enno Shioji
Hi, I hit an exception, can you help me?
what is the exception?
TofuBeer
Class can not access a member of class with modifiers "private" reflect
member.setAccessible(true)
Bozho
+2  A: 

Really, really, really you do not want to do this! Well you may want to do it... but you really really really should not do it.

Rather than use reflection make use of the language and provide a constructor like this:

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();
    }
}

Things to fix in your code:

  • do not declare that a method "throws Exception" since you then have to have "catch(Exception ex)" and that can cause you to hide errors in your code.

  • (guessing) at the very least in the catch block do "ex.printStackTrace()" (or log it) so you can see if something has gone wrong.

TofuBeer
sorry, read that question and I don't really understand the issue. I do appreciate that English is not your first language, but you are going to have to clear up your question to make it a bit more understandable.
TofuBeer
+1  A: 

The reaasons behind what you are trying to do would be strange (share them), but there are better approaches than using reflection manually.

  1. Apache commons-beanutils BeanUtils.copyProperties(source, target)
  2. Spring's BeanUtils.copyProperties(source, target)

But you will need public setters/getters for the properties you want to copy (and you should have them anyway), and you will have to create the instance of the target object beforehand.

Bozho