简体   繁体   English

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

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

I'm newbie on reflection and I try to exercise with it... 我是反思的新手,我试着用它锻炼......

This is the code... 这是代码......

 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();
        }

    }

I think that is a stupid question.. On XXXXX I want an object with the type and value of value getted... 我认为这是一个愚蠢的问题..在XXXXX上我想要一个具有值类型和值的对象...

I thought that was useful... but is not.. 我认为这很有用......但不是..

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

Help! 救命!

You might want to look at the code for BeanUtils from apache commons. 您可能希望从apache commons查看BeanUtils的代码。 The following functions should be useful cloneBean() and copyProperties(). 以下函数应该是有用的cloneBean()和copyProperties()。

The correct code should look as follows: Things to note: - need to use getDeclaredFields() - getters don't start with get for boolean fields - setter.invoke() needs to be called with the correct params - use of field.getType() while getting the setter [handles primitive types] 正确的代码应该如下所示:需要注意的事项: - 需要使用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 +
                '}';
    }
}

Given a getter Method m , 给出一个getter Method m

m.getReturnType().newInstance()

will construct an instance as long as f 's type is a public concrete type (not an interface or abstract class) with a public zero argument constructor. 只要f的类型是具有public零参数构造函数的public具体类型(不是接口或抽象类),就会构造一个实例。 And it won't work for public, non-static inner classes. 它不适用于公共的,非静态的内部类。

It also won't work for primitive return types like Integer.TYPE . 它也不适用于Integer.TYPE等原始返回类型。

So given that large set of caveats, your best bet is to write a method that looks at the return type and creates an object. 因此,考虑到大量的警告,最好的办法是编写一个查看返回类型并创建对象的方法。 That way, you can return Collections.emptyList() for the abstract but commonly used return type List , and can return 0 for int . 这样,您可以为抽象但常用的返回类型List返回Collections.emptyList() ,并且可以为int返回0

I think it's much more simple if you want juste get and set value of a field by using methods provides by Java Reflection API rather than trying to get getters and setters method's names manually. 我认为如果你想通过使用Java Reflection API提供的方法而不是试图手动获取getter和setters方法的名称来获取juste get和设置字段值,那就简单得多了。

This type of function can be used to get a field value : 这种类型的函数可用于获取字段值:

Object getFieldValue(Field afield, Object obj){

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

   return field.get(obj);

}

You can get the value of field by using the field.set(obj,value) ... 您可以使用field.set(obj,value)获取字段的值...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 用Java反射如何实例化一个新对象,然后调用一个方法就可以了? - With Java reflection how to instantiate a new object, then call a method on it? Java 反射 - 从对象获取类型以实例化泛型 - Java Reflection - Getting a Type from an object to instantiate a generic Java Reflection如何实例化类字段类型 - Java Reflection How to instantiate class field type 使用Java反射的getReturnType()创建该类型的新对象 - Use of getReturnType() of Java's reflection to create a new object of that type 实例化一个对象并使用JAVA中的反射通过.class文件调用方法? - instantiate an object and invoking a method via a .class file using reflection in JAVA? 如何实例化列表 <someType> 那是空的并且是在使用反射的对象内部吗? 或实例化列表类型的对象 - How to instantiate a List<someType> that is null and is inside an object using reflection? OR instantiate an object of the type of the list Java上的类型不匹配,并且无法实例化对象的类型 - Type mismatch on java and cannot instantiate the type of object Java 反射在运行时实例化 Generics - Java Reflection to Instantiate Generics at Runtime 无法实例化类对象的类型(Java) - Cannot instantiate the type for class object (Java) 通过反射来实例化参数化类型是不可能的吗? - Is it impossible to instantiate a parameterized type through reflection?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM