反射 - 读取类型的属性而不是字符串或int

时间:2015-06-22 07:46:19

标签: java reflection

我正在使用Reflection来读取属性及其类的值。有字符串,布尔值和类类型的属性。如何获取类类型的值。

User.java

private String firstName;
private String lastName;
private SupportLangauge flang;
private SupportLangauge mlang;

SupportLanguage.java

private String languageCode;
private Boolean flang;
private Boolean mlang;

我可以使用反射保存flang,mlang的数据,但无法读取值。当我读到时,正在返回该对象。见下面的示例。

结果:

       "flang": "com.sample.entity.user.SupportLanguage@3080037d
          [\r\n     languageCode=EN_US\r\n]",
       "mlang": "com.sample.entity.user.SupportLanguage@3080037d
          [\r\n  languageCode=EN_US\r\n]",

下面的代码用于保存语言类型。

SavingUser.java

for (User user : CollectionsUtilService.nullGuard(userList)) {
 PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(
   user.getClass()).getPropertyDescriptors();
for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
if (fieldValueMap.containsKey(propertyDescriptor.getName())) {
if   (propertyDescriptor.getPropertyType().getName().
 equalsIgnoreCase("com.sample.entity.user.SupportLanguage")) {
                    String langString =   fieldValueMap.
             get(propertyDescriptor.getName());
             SupportLanguage s = new SupportLanguage();
                    s.setLanguageCode(langString);
                    propertyDescriptor.getWriteMethod().invoke(user, s);
                }                   

            }
        }
    }

我的阅读价值代码;

RenderingUser.java

               if (propertyDescriptor.getPropertyType().
                 getName().equalsIgnoreCase
               ("com.sample.entity.
                  user.SupportLanguage")) {
                  Method m = propertyDescriptor.getReadMethod();
                  SupportLanguage s = new SupportLanguage();
                  System.out.println("m.invoke(SupportLanguage) " 
                  +  m.invoke(s));  

3 个答案:

答案 0 :(得分:0)

你的阅读几乎是正确的。但是您必须使用根对象(User)而不是属性对象。

User user = ...; // Initialized user object
           if (propertyDescriptor.getPropertyType().
             getName().equalsIgnoreCase
           ("com.sample.entity.
              user.SupportLanguage")) {
              Method m = propertyDescriptor.getReadMethod();
              SupportLanguage s = m.invoke(user);
              System.out.println("languageCode: " + s.getLanguageCode()); 

答案 1 :(得分:0)

如果您实现了Java Bean标准(即具有正确名称的getter方法),那么我建议使用Apache BeanUtils包。

PropertyUtils.getSimpleProperty(Object, String)会为您提供所需的财产,还有一种简单的方法可以获得nested properties

最后,你有one neat method给oyu所有有吸气剂进入地图的属性

答案 2 :(得分:0)

而不是使用java bean API,您也可以使用纯反射,如下例所示。关键是要将私有字段设置为可访问的,如果vm在对此有限制的安全环境上运行,则可能导致可访问性异常。但是对于这种情况,您可以使您的财产受到保护。

public class GetPropertyTest {

@Test
public void testGetFLang() throws Exception {
    User user = new User();

    Field declaredField = user.getClass().getDeclaredField( "flang" );
    declaredField.setAccessible( true );

    // get the value
    SupportLanguage flang = (SupportLanguage) declaredField.get( user );

    assertEquals( 
        "SupportLanguage [languageCode=lang1, flang=true, mlang=true]", 
        flang.toString() 
    );

    // set new value
    declaredField.set( user, new SupportLanguage( "lang3", false, false ) );
    assertEquals(
        "User [firstName=null, lastName=null, "
        + "flang=SupportLanguage [languageCode=lang3, flang=false, mlang=false], "
        + "mlang=SupportLanguage [languageCode=lang2, flang=true, mlang=true]]",
        user.toString()
    );
}

@Test
public void testSetValuesFromMap() throws Exception {
    Map<String, Object> valueMap = new HashMap<String, Object>();
    valueMap.put( "firstName", "Jon" );
    valueMap.put( "lastName", "Doo" );
    valueMap.put( "flang", new SupportLanguage( "langFormMap1", true, true ) );
    valueMap.put( "mlang", new SupportLanguage( "langFormMap2", true, true ) );

    User user = new User();

    for ( Map.Entry<String, Object> entry : valueMap.entrySet() ) {
        String fieldName = entry.getKey();
        Object fieldValue = entry.getValue();
        Field declaredField = user.getClass().getDeclaredField( fieldName );
        declaredField.setAccessible( true );
        declaredField.set( user, fieldValue );
    }

    assertEquals(
        "User ["
        + "firstName=Jon, "
        + "lastName=Doo, "
        + "flang=SupportLanguage [languageCode=langFormMap1, flang=true, mlang=true], "
        + "mlang=SupportLanguage [languageCode=langFormMap2, flang=true, mlang=true]]",
        user.toString()
    );
}

public class User {
    private String firstName;
    private String lastName;
    private SupportLanguage flang = new SupportLanguage( "lang1", true, true );
    private SupportLanguage mlang = new SupportLanguage( "lang2", true, true );
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append( "User [firstName=" );
        builder.append( firstName );
        builder.append( ", lastName=" );
        builder.append( lastName );
        builder.append( ", flang=" );
        builder.append( flang );
        builder.append( ", mlang=" );
        builder.append( mlang );
        builder.append( "]" );
        return builder.toString();
    }

}

public class SupportLanguage {

    private String languageCode;
    private Boolean flang;
    private Boolean mlang;


    public SupportLanguage( String languageCode, Boolean flang, Boolean mlang ) {
        super();
        this.languageCode = languageCode;
        this.flang = flang;
        this.mlang = mlang;
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append( "SupportLanguage [languageCode=" );
        builder.append( languageCode );
        builder.append( ", flang=" );
        builder.append( flang );
        builder.append( ", mlang=" );
        builder.append( mlang );
        builder.append( "]" );
        return builder.toString();
    }
}

}