Java反射:实例化具有指定类型的新对象

Java反射:实例化具有指定类型的新对象,java,Java,我是反思的新手,我试着用它来锻炼 这是代码 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()

我是反思的新手,我试着用它来锻炼

这是代码

 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上,我想要一个类型和值为value getted的对象

我觉得这很有用。。。但不是

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

救命啊

您可能想看看apache commons中的代码。以下函数应该对cloneBean和copyProperties很有用。

您可能需要查看apache commons中的代码。以下函数应该对cloneBean和copyProperties有用。

给定getter方法m

只要f的类型是公共具体类型,而不是带有公共零参数构造函数的接口或抽象类,则将构造实例。而且它不适用于公共的、非静态的内部类

它也不适用于Integer.TYPE之类的基本返回类型

因此,考虑到大量的警告,您最好编写一个方法来查看返回类型并创建一个对象。这样,您可以为抽象但常用的返回类型列表返回Collections.emptyList,为int返回0。

给定getter方法m

只要f的类型是公共具体类型,而不是带有公共零参数构造函数的接口或抽象类,则将构造实例。而且它不适用于公共的、非静态的内部类

它也不适用于Integer.TYPE之类的基本返回类型


因此,考虑到大量的警告,您最好编写一个方法来查看返回类型并创建一个对象。这样,您就可以为抽象但常用的返回类型列表返回Collections.emptyList,为int返回0。

正确的代码如下所示: 注意事项: -需要使用getDeclaredFields -对于布尔字段,getter不以get开头 -需要使用正确的参数调用setter.invoke -获取setter[处理基元类型]时使用field.getType

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 +
                '}';
    }
}

正确的代码应如下所示: 注意事项: -需要使用getDeclaredFields -对于布尔字段,getter不以get开头 -需要使用正确的参数调用setter.invoke -获取setter[处理基元类型]时使用field.getType

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 +
                '}';
    }
}

我认为,如果您只想通过使用Java反射API提供的方法来获取和设置字段的值,而不是试图手动获取getter和setters方法的名称,那么这会简单得多

此类型的函数可用于获取字段值:

Object getFieldValue(Field afield, Object obj){

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

   return field.get(obj);

}

您可以通过使用field.setobj,value…

来获取字段的值。我认为,如果您只想通过使用Java反射API提供的方法来获取和设置字段的值,而不是试图手动获取getter和setter方法的名称,这会简单得多

此类型的函数可用于获取字段值:

Object getFieldValue(Field afield, Object obj){

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

   return field.get(obj);

}

您可以使用field.setobj,value…,获取field的值。

您想做什么?如果只在类数组中放置一个项,为什么要创建类数组?getName将始终返回一个字符串,您是否尝试检查得到的值是否为字符串?代码不完整,很明显。类的数组正在进行中。。现在有1个元素,因为它正在测试中。。“如果”是垃圾。。刚刚纠正…我建议你看看内省课程。它支持getter/setter的发现和使用您想做什么?如果只在类数组中放置一个项,为什么要创建类数组?getName将始终返回一个字符串,您是否尝试检查得到的值是否为字符串?代码不完整,很明显。类的数组正在进行中。。现在有1个元素,因为它正在测试中。。“如果”是垃圾。。刚刚纠正…我建议你看看内省课程。它支持发现和使用getter/setterYes!这是我想要的吗。。我会用小扁豆。。但是在这一点上。。我想解决这个问题;对这是我想要的吗。。我会用小扁豆。。但是在这一点上。。我想解决这个问题;谢谢。。。我犯了两个错误。。在代码中,对象P与您称之为克隆的对象相同。。但是在代码示例中,我省略了它。。很抱歉第二是。。我使用错误的参数调用调用方法。我传递了一个类而不是对象的实例。非常感谢。。。我犯了两个错误。。在代码中,对象P与您称之为克隆的对象相同。。但是在代码示例中,我省略了它。。很抱歉第二是。。我使用错误的参数调用调用方法。我传递了一个类而不是对象的实例。