Search code examples
javareflection

Java Reflection - Invoke valueOf on different types


I am trying to invoke the valueOf method on different types such as Integer, String,... using reflection.

I want to know how to call this method using reflection with only one getMehod().

The problem is when the type is java.lang.String the valueOf method doesn't accept the String parameter and when it is Integer or other types the valueOf method doesn't accept the Object.class .

I used one if clause to differentiate them as you can see below but I want to remove the if clause.

private static void setFieldValue(String fieldName, String fieldValue, Rule rule) throws Exception {
        Field field = Rule.class.getDeclaredField(fieldName);
        field.setAccessible(true);
        Class<?> type = field.getType();
        Method valueOf;

        // here I checked the type

        if (String.class.equals(type))
            valueOf = type.getMethod("valueOf", Object.class);
        else
            valueOf = type.getMethod("valueOf", String.class);
        field.set(rule, valueOf.invoke(null, fieldValue));
}

Solution

  • You can use the types constructor (with String arg) instead of the valueOf method :

    static class Rule {
        private String stringField;
        private Integer integerField;
        private Double doubleField;
        private Long longField;
        private Boolean booleanField;
        private BigDecimal bigDecimalField;
    }
    
    public static void main(String[] args) throws Exception {
        Rule rule = new Rule();
        setFieldValue(rule, "stringField", "string val");
        setFieldValue(rule, "integerField", "12");
        setFieldValue(rule, "doubleField", "1.23");
        setFieldValue(rule, "longField", "19877754");
        setFieldValue(rule, "booleanField", "false");
        setFieldValue(rule, "bigDecimalField", "879565.3565754");
        System.out.println(rule.stringField);
        System.out.println(rule.integerField);
        System.out.println(rule.doubleField);
        System.out.println(rule.longField);
        System.out.println(rule.booleanField);
        System.out.println(rule.bigDecimalField);
    }
    
    private static void setFieldValue(Rule rule, String fieldName, String fieldValue) throws Exception {
        Field field = Rule.class.getDeclaredField(fieldName);
        field.setAccessible(true);
        Class<?> type = field.getType();
        Constructor<?> valueOf = type.getConstructor(String.class);
        field.set(rule, valueOf.newInstance(fieldValue));
    }
    

    Output :

    string val
    12
    1.23
    19877754
    false
    879565.3565754