【问题标题】:Java Reflection - how to set value for the class which are extended from One and TwoJava Reflection - 如何为从一和二扩展的类设置值
【发布时间】:2013-04-24 03:20:36
【问题描述】:

目标:

设置类字段以及扩展类字段的值

示例:

public class CreateRequisitionRO extends AbstractPortfolioSpecificRO {....}

我可以为CreateRequisitionRO 设置值,但无法为正在扩展的AbstractPortfolioSpecificRO 设置值。

这就是我设置值的方式:

public Object creatObjectWithDefaultValue(String className) throws IllegalArgumentException, IllegalAccessException, InstantiationException {
        Class<?> objectClass = null;
        Object clsObject =null;
        try {
            objectClass = Class.forName(className);
            clsObject = objectClass.newInstance();
             Field[] fields = objectClass.getDeclaredFields();
             for(Field f:fields){
                  if(!f.isAccessible()){
                        f.setAccessible(true);
                        Class<?> type = f.getType();
                        if(! Modifier.isFinal(f.getModifiers()) && type.equals(Integer.class)){
                            f.set(clsObject, DefaultParamValuesEnum.INTEGER.getDefaultInt());  
                        } else if( !Modifier.isFinal(f.getModifiers()) && type.equals(java.math.BigDecimal.class)){
                            f.set(clsObject, DefaultParamValuesEnum.BIGDECIMAL.getDdefaultBigDecimal());  
                        } else if(! Modifier.isFinal(f.getModifiers()) && type.equals(org.joda.time.LocalDate.class)){
                            f.set(clsObject,DefaultParamValuesEnum.DATE.getDefaultDate());  
                        }  else if(! Modifier.isFinal(f.getModifiers()) && type.equals(boolean.class)){
                            f.set(clsObject, DefaultParamValuesEnum.BOOLEAN.getDefaultBoolean());  
                        } else if(! Modifier.isFinal(f.getModifiers()) && type.equals(java.lang.String.class)){
                            f.set(clsObject, DefaultParamValuesEnum.STRING.getDefaultString());  
                        }
                        else if(! Modifier.isFinal(f.getModifiers()) && type.equals(long.class)){
                            f.set(clsObject,DefaultParamValuesEnum.LONGVALUE.getDefaultLong());  
                        }
                     }
               }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return clsObject;
    }

这就是我调用上述方法的方式:

classObject.creatJSONObject("com.hexgen.ro.request.CreateRequisitionRO");

上述方式为CreateRequisitionRO中可用的所有字段设置值,而不是扩展类中可用的字段。

如何设置?

【问题讨论】:

  • 您应该将此检查包裹在其他检查周围:if(! Modifier.isFinal(f.getModifiers())),而不是一遍又一遍地进行相同的检查

标签: java dynamic reflection javabeans


【解决方案1】:

您可以使用clazz.getSuperclass() 来检索CreateRequisitionRO 的超类型。一旦你掌握了超类型 AbstractPortfolioSpecificRO 的句柄,你就可以迭代它的字段。我建议将所有这些字段存储在 List&lt;Field&gt; 中。遍历此列表并根据您的条件逻辑设置字段。

我提供了一个快速示例来说明如何执行此操作。在我的示例中,Child 扩展了 Parent。递归getFields 方法返回一个List&lt;Field&gt;,其中包含Child 的所有字段。然后我遍历List&lt;Field&gt; 为每个设置值。请注意,我必须切换私有字段的可访问性。

Child.Java

public class Child extends Parent {
    public String a;
    public String b;


    public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException {
        Child child = new Child();
        List<Field> fields = getFields(child.getClass());

        for(Field f: fields){
            f.setAccessible(true);
            f.set(child, "Test");
        }

        for(Field fd: fields){
            System.out.println(fd.get(child));
            fd.setAccessible(false);
        }


    }

    public static List<Field> getFields(Class<?> clazz){
        List<Field> list = new ArrayList<Field>();
        list.addAll(Arrays.asList(clazz.getDeclaredFields()));

        if(clazz.getSuperclass() != null){
            list.addAll(getFields(clazz.getSuperclass()));
        }
        return list;
    }
}

Parent.java

public class Parent {
    private String x;
    public String y;
    protected String z;

}

【讨论】:

  • 感谢您的精彩解释 +1。会这样做并将其标记为答案,因为这也会对其他人有所帮助。
  • @Anto 很高兴我能帮上忙。如果您还有其他问题,请告诉我。
  • 凯文,当我使用getSuperclass(). 时,我只得到类似以下userId 的字段名称,但我需要像private java.lang.String com.hexgen.ro.request.CreateRequisitionRO.custodianN 这样有可能
  • getDeclaredFields 也应该提取私有字段。
【解决方案2】:

您可以使用Class&lt;SuperClass&gt; superClazz = clazz.getSuperclass();获得您班级的超级班级

一旦得到,使用superClazz.getFields()获取Field[]并使用Fieldset方法

【讨论】:

    【解决方案3】:

    使用getSuperclass()方法获取超类的类对象。然后以类似的方式获取超类的字段。

    【讨论】:

      【解决方案4】:
      obj.getClass().getSuperclass().getDeclaredFields();
      

      您可以使用上述功能来实现相同的..

      也检查Access to private inherited fields via reflection in Java

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-30
        • 1970-01-01
        • 2016-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多