簡體   English   中英

Java反射:實例化具有指定類型的新對象

[英]Java Reflection: Instantiate a new object with specified type

我是反思的新手,我試着用它鍛煉......

這是代碼......

 for (java.lang.reflect.Field field : fields) {

        String getter = "get"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
        String setter = "set"+field.getName().substring(0,1).toUpperCase()+field.getName().substring(1);
        java.lang.reflect.Method getterMethod;
        java.lang.reflect.Method setterMethod;

        try {
             getterMethod = this.getClass().getMethod(getter, null);
             Object valueGetted = getterMethod.invoke(this, null);

             Class[] paramForSetter = new Class[1];
             paramForSetter[0] = valueGetted.getClass();



             setterMethod = p.getClass().getMethod(setter, paramForSetter);
             setterMethod.invoke(p.getClass(),XXXX); 

             System.out.println("");

        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-Trace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

我認為這是一個愚蠢的問題..在XXXXX上我想要一個具有值類型和值的對象...

我認為這很有用......但不是..

        setterMethod.invoke(p.getClass(),(valueGetted.getClass().getName())  valueGetted );

救命!

您可能希望從apache commons查看BeanUtils的代碼。 以下函數應該是有用的cloneBean()和copyProperties()。

正確的代碼應該如下所示:需要注意的事項: - 需要使用getDeclaredFields() - getters不以get for boolean fields開頭 - 需要使用正確的params調用setter.invoke() - 使用field.getType ()獲取setter [處理原始類型]

import java.lang.reflect.Field;

public class Main {

    private static MyObject clone(MyObject p) {

        final MyObject clone = new MyObject();
        Field[] fields = p.getClass().getDeclaredFields();

        for (java.lang.reflect.Field field : fields) {

            // Boolean properties will hav eis prefix instead of get
            String getter = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
            String setter = "set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
            java.lang.reflect.Method getterMethod;
            java.lang.reflect.Method setterMethod;

            try {
                getterMethod = p.getClass().getMethod(getter, null);
                Object valueGetted = getterMethod.invoke(p, null);

                Class[] paramForSetter = new Class[1];
                paramForSetter[0] = valueGetted.getClass();

                setterMethod = p.getClass().getMethod(setter, field.getType());
                setterMethod.invoke(clone, valueGetted);

                System.out.println(" Successfully copied " + field.getName());

            } catch (Exception ex) {
                System.err.println(" Error copying " + field.getName() + ": " + ex.getMessage());
            }
        }
        return clone;
    }

    public static void main(String[] args) {
        MyObject m = new MyObject(1, 2L, "3", true);
        System.out.println("Main.main: Original = " + m);
        MyObject c = clone(m);
        System.out.println("Main.main: Clone = " + c);
    }

}

class MyObject {

    private int myInt;
    private Long myLong;
    private String myString;
    private Boolean myBool;

    MyObject() {
    }

    MyObject(int myInt, Long myLong, String myString, Boolean myBool) {
        this.myInt = myInt;
        this.myLong = myLong;
        this.myString = myString;
        this.myBool = myBool;
    }

    public int getMyInt() {
        return myInt;
    }

    public void setMyInt(int myInt) {
        this.myInt = myInt;
    }

    public Long getMyLong() {
        return myLong;
    }

    public void setMyLong(Long myLong) {
        this.myLong = myLong;
    }

    public String getMyString() {
        return myString;
    }

    public void setMyString(String myString) {
        this.myString = myString;
    }

    public Boolean isMyBool() {
        return myBool;
    }

    public void setMyBool(Boolean myBool) {
        this.myBool = myBool;
    }

    @Override
    public String toString() {
        return "MyObject{" +
                "myInt=" + myInt +
                ", myLong=" + myLong +
                ", myString='" + myString + '\'' +
                ", myBool=" + myBool +
                '}';
    }
}

給出一個getter Method m

m.getReturnType().newInstance()

只要f的類型是具有public零參數構造函數的public具體類型(不是接口或抽象類),就會構造一個實例。 它不適用於公共的,非靜態的內部類。

它也不適用於Integer.TYPE等原始返回類型。

因此,考慮到大量的警告,最好的辦法是編寫一個查看返回類型並創建對象的方法。 這樣,您可以為抽象但常用的返回類型List返回Collections.emptyList() ,並且可以為int返回0

我認為如果你想通過使用Java Reflection API提供的方法而不是試圖手動獲取getter和setters方法的名稱來獲取juste get和設置字段值,那就簡單得多了。

這種類型的函數可用於獲取字段值:

Object getFieldValue(Field afield, Object obj){

   if(!field.isAccessible()) field.setAccessible(true);

   return field.get(obj);

}

您可以使用field.set(obj,value)獲取字段的值...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM