Salve a tutti.

Non ho lavorato molto con la Reflection e ora mi trovo a scrivere un metodo che debba impostare il valore di un field con il valore di una oggetto di tipo sconosciuto (istanza di Object).

Ho scritto un programmino di esempio per mostrare dove non riesco a trovare soluzione. Elenco alcuni punti fondamentali:
- ho una classe con 4 fields di cui 2 int e 2 Integer.
- alla linea 27 imposto il nome del field che voglio modificare
- se imposto field1 o field2 (entrambi di tipo primitivo int) non c'é problema. Viene eseguito il 'case "int"' del successivo switch
- se imposto field3 o field4 (di tipo Integer) viene eseguito il 'default' dello switch e mi dá eccezione alla linea 56 "Cannot cast java.lang.String to java.lang.Integer"

Qualcuno sa aiutarmi? Grazie in anticipo.
codice:
import java.lang.reflect.Field;

public class TestClass {
    public int field1 = 1;
    public int field2 = 2;
    public Integer field3 = new Integer(3);
    public Integer field4 = new Integer("4");
    
    public static void main(String[] args) {
        try {
            TestClass object = new TestClass();
            Object newValue = "9999999";
            Field[] fields = object.getClass().getDeclaredFields();
            System.out.println("Execution 1");
            for (Field field : fields) {
                System.out.print("Field name: ");
                System.out.print(field.getName());
                System.out.print(" - Type: ");
                System.out.print(field.getType().getName());
                System.out.print(" - Value: ");
                System.out.print(field.get(object).toString());
                Object value = field.get(object);
                System.out.print(" - Value type: ");
                System.out.print(value.getClass().getName());
                System.out.println();
            }
            Field f = object.getClass().getField("field3");
            f.setAccessible(true);
            switch (f.getType().getName()) {
                case "boolean":
                    f.setBoolean(object, Boolean.parseBoolean(newValue.toString()));
                    break;
                case "byte":
                    f.setByte(object, (newValue.toString().getBytes()[0]));
                    break;
                case "char":
                    f.setChar(object, (newValue.toString().charAt(0)));
                    break;
                case "double":
                    f.setDouble(object, Double.parseDouble(newValue.toString()));
                    break;
                case "float":
                    f.setFloat(object, Float.parseFloat(newValue.toString()));
                    break;
                case "int":
                    f.setInt(object, Integer.parseInt(newValue.toString()));
                    break;
                case "long":
                    f.setLong(object, Long.parseLong(newValue.toString()));
                    break;
                case "short":
                    f.setShort(object, Short.parseShort(newValue.toString()));
                    break;
                default:
                    newValue = f.getType().cast(newValue);
                    f.set(object, newValue);
                    break;
            }
            
            System.out.println("Execution 2");
            for (Field field : fields) {
                System.out.print("Field name: ");
                System.out.print(field.getName());
                System.out.print(" - Type: ");
                System.out.print(field.getType().getName());
                System.out.print(" - Value: ");
                System.out.print(field.get(object).toString());
                Object value = field.get(object);
                System.out.print(" - Value type: ");
                System.out.print(value.getClass().getName());
                System.out.println();
            }
        } catch (NoSuchFieldException ex) {
            System.out.println("NoSuchFieldException: " + ex.getMessage());
        } catch (SecurityException ex) {
            System.out.println("SecurityException: " + ex.getMessage());
        } catch (Throwable ex) {
            System.out.println("Throwable: " + ex.getMessage());
            ex.printStackTrace();
        }
    }
}