ホームページ > Java > &#&チュートリアル > Javaリフレクションの詳しい説明

Javaリフレクションの詳しい説明

高洛峰
リリース: 2016-12-12 11:55:12
オリジナル
1313 人が閲覧しました

1. オブジェクトを通じて完全なパッケージ名とクラス名を取得します

Java コード

package Reflect;  
   
/** 
 * 通过一个对象获得完整的包名和类名 
 * */  
class Demo{  
    //other codes...  
}  
   
class hello{  
    public static void main(String[] args) {  
        Demo demo=new Demo();  
        System.out.println(demo.getClass().getName());  
    }  
}
ログイン後にコピー

[実行結果]: Reflect.Demo
文を追加します: すべてのクラス オブジェクトは実際には Class のインスタンスです。
2. Class オブジェクトをインスタンス化します

Java コード

package Reflect;  
class Demo{  
    //other codes...  
}  
   
class hello{  
    public static void main(String[] args) {  
        Class<?> demo1=null;  
        Class<?> demo2=null;  
        Class<?> demo3=null;  
        try{  
            //一般尽量采用这种形式  
            demo1=Class.forName("Reflect.Demo");  
        }catch(Exception e){  
            e.printStackTrace();  
        }  
        demo2=new Demo().getClass();  
        demo3=Demo.class;  
           
        System.out.println("类名称   "+demo1.getName());  
        System.out.println("类名称   "+demo2.getName());  
        System.out.println("类名称   "+demo3.getName());  
           
    }  
}
ログイン後にコピー

[実行結果]:

クラス名 Reflect.Demo

クラス名 Reflect.Demo

3. Class Object を通じて他のオブジェクトをインスタンス化します。 of class
引数なしの構築によるオブジェクトのインスタンス化

Java コード

package Reflect;  
   
class Person{  
       
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public int getAge() {  
        return age;  
    }  
    public void setAge(int age) {  
        this.age = age;  
    }  
    @Override  
    public String toString(){  
        return "["+this.name+"  "+this.age+"]";  
    }  
    private String name;  
    private int age;  
}  
   
class hello{  
    public static void main(String[] args) {  
        Class<?> demo=null;  
        try{  
            demo=Class.forName("Reflect.Person");  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        Person per=null;  
        try {  
            per=(Person)demo.newInstance();  
        } catch (InstantiationException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        } catch (IllegalAccessException e) {  
            // TODO Auto-generated catch block  
            e.printStackTrace();  
        }  
        per.setName("Rollen");  
        per.setAge(20);  
        System.out.println(per);  
    }  
}
ログイン後にコピー

[実行結果]:

[Rollen 20]

ただし、たとえば、次の後に、 Person でデフォルトの引数なしのコンストラクタをキャンセルするときは注意してください。パラメーター付きのコンストラクターのみを定義すると、エラーが表示されます:

たとえば、コンストラクターを定義すると:

Java コード

public Person(String name, int age) {  
        this.age=age;  
        this.name=name;  
    }
ログイン後にコピー

その後、上記のプログラムを実行し続けると、エラーが表示されます:

Java コード

java.lang.InstantiationException: Reflect.Person  
  
    at java.lang.Class.newInstance0(Class.java:340)  
  
    at java.lang.Class.newInstance(Class.java:308)  
  
    at Reflect.hello.main(hello.java:39)  
  
Exception in thread "main" java.lang.NullPointerException  
  
    at Reflect.hello.main(hello.java:47)
ログイン後にコピー

そのため、今後 Class を使用して他のクラスをインスタンス化するオブジェクトを作成する場合は、独自のパラメーターなしのコンストラクターを定義する必要があります

4. Class を通じて他のクラスのコンストラクターを呼び出します (この方法で Class を通じてコン​​ストラクターを作成することもできます)。クラス)

Java コード

package Reflect;  
   
import java.lang.reflect.Constructor;  
   
class Person{  
       
    public Person() {  
           
    }  
    public Person(String name){  
        this.name=name;  
    }  
    public Person(int age){  
        this.age=age;  
    }  
    public Person(String name, int age) {  
        this.age=age;  
        this.name=name;  
    }  
    public String getName() {  
        return name;  
    }  
    public int getAge() {  
        return age;  
    }  
    @Override  
    public String toString(){  
        return "["+this.name+"  "+this.age+"]";  
    }  
    private String name;  
    private int age;  
}  
   
class hello{  
    public static void main(String[] args) {  
        Class<?> demo=null;  
        try{  
            demo=Class.forName("Reflect.Person");  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        Person per1=null;  
        Person per2=null;  
        Person per3=null;  
        Person per4=null;  
        //取得全部的构造函数  
        Constructor<?> cons[]=demo.getConstructors();  
        try{  
            per1=(Person)cons[0].newInstance();  
            per2=(Person)cons[1].newInstance("Rollen");  
            per3=(Person)cons[2].newInstance(20);  
            per4=(Person)cons[3].newInstance("Rollen",20);  
        }catch(Exception e){  
            e.printStackTrace();  
        }  
        System.out.println(per1);  
        System.out.println(per2);  
        System.out.println(per3);  
        System.out.println(per4);  
    }  
}
ログイン後にコピー

[実行結果]:

[null 0]

[Rollen 0]

[null 20]

[Rollen 20]

5. クラス実装インターフェース

Java を返します。コード

package Reflect;  
   
interface China{  
    public static final String name="Rollen";  
    public static  int age=20;  
    public void sayChina();  
    public void sayHello(String name, int age);  
}  
   
class Person implements China{  
    public Person() {  
           
    }  
    public Person(String sex){  
        this.sex=sex;  
    }  
    public String getSex() {  
        return sex;  
    }  
    public void setSex(String sex) {  
        this.sex = sex;  
    }  
    @Override  
    public void sayChina(){  
        System.out.println("hello ,china");  
    }  
    @Override  
    public void sayHello(String name, int age){  
        System.out.println(name+"  "+age);  
    }  
    private String sex;  
}  
   
class hello{  
    public static void main(String[] args) {  
        Class<?> demo=null;  
        try{  
            demo=Class.forName("Reflect.Person");  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        //保存所有的接口  
        Class<?> intes[]=demo.getInterfaces();  
        for (int i = 0; i < intes.length; i++) {  
            System.out.println("实现的接口   "+intes[i].getName());  
        }  
    }  
}
ログイン後にコピー

[実行結果]:

実装インターフェース Reflect.China

6. 他のクラスの親クラスを取得

Java コード

class hello{  
    public static void main(String[] args) {  
        Class<?> demo=null;  
        try{  
            demo=Class.forName("Reflect.Person");  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        //取得父类  
        Class<?> temp=demo.getSuperclass();  
        System.out.println("继承的父类为:   "+temp.getName());  
    }  
}
ログイン後にコピー


[実行結果]

継承 親クラスは: java .lang.Object

7. 他のクラスのすべてのコンストラクターを取得します

Java コード

class hello{  
    public static void main(String[] args) {  
        Class<?> demo=null;  
        try{  
            demo=Class.forName("Reflect.Person");  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        Constructor<?>cons[]=demo.getConstructors();  
        for (int i = 0; i < cons.length; i++) {  
            System.out.println("构造方法:  "+cons[i]);  
        }  
    }  
}
ログイン後にコピー

[実行結果]:

構築メソッド: public Reflect.Person()

構築メソッド: public Reflect.Person(java. lang.String)

しかし、注意深い読者は、上記のコンストラクターには public や private などの修飾子がないことがわかるでしょう

次の例では、修飾子を取得します


Java コード

class hello{  
    public static void main(String[] args) {  
        Class<?> demo=null;  
        try{  
            demo=Class.forName("Reflect.Person");  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        Constructor<?>cons[]=demo.getConstructors();  
        for (int i = 0; i < cons.length; i++) {  
            Class<?> p[]=cons[i].getParameterTypes();  
            System.out.print("构造方法:  ");  
            int mo=cons[i].getModifiers();  
            System.out.print(Modifier.toString(mo)+" ");  
            System.out.print(cons[i].getName());  
            System.out.print("(");  
            for(int j=0;j<p.length;++j){  
                System.out.print(p[j].getName()+" arg"+i);  
                if(j<p.length-1){  
                    System.out.print(",");  
                }  
            }  
            System.out.println("){}");  
        }  
    }  
}
ログイン後にコピー

[実行結果] :

構築メソッド: public Reflect.person(){}

構築メソッド: public Reflect.Person(java.lang.String arg1){}

場合によっては、メソッドに異常がある場合もあります (笑)。以下を見てください:

Java コード

class hello{  
    public static void main(String[] args) {  
        Class<?> demo=null;  
        try{  
            demo=Class.forName("Reflect.Person");  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        Method method[]=demo.getMethods();  
        for(int i=0;i<method.length;++i){  
            Class<?> returnType=method[i].getReturnType();  
            Class<?> para[]=method[i].getParameterTypes();  
            int temp=method[i].getModifiers();  
            System.out.print(Modifier.toString(temp)+" ");  
            System.out.print(returnType.getName()+"  ");  
            System.out.print(method[i].getName()+" ");  
            System.out.print("(");  
            for(int j=0;j<para.length;++j){  
                System.out.print(para[j].getName()+" "+"arg"+j);  
                if(j<para.length-1){  
                    System.out.print(",");  
                }  
            }  
            Class<?> exce[]=method[i].getExceptionTypes();  
            if(exce.length>0){  
                System.out.print(") throws ");  
                for(int k=0;k<exce.length;++k){  
                    System.out.print(exce[k].getName()+" ");  
                    if(k<exce.length-1){  
                        System.out.print(",");  
                    }  
                }  
            }else{  
                System.out.print(")");  
            }  
            System.out.println();  
        }  
    }  
}
ログイン後にコピー

[実行結果]:

public java.lang.String getSex ()

public void setSex (java.lang.String arg0)

public voidsayChina ()

public voidsayHello (java.lang.String arg0,int arg1)

publicfinalnative voidwait(longarg0)throws java.lang.InterruptedException

publicfinal voidwait()throws java.lang.InterruptedException

publicfinal void wait (long arg0,int arg1) は java.lang.InterruptedException をスローします

public boolean = (java.lang.Object arg0)

public java.lang.String toString ()

publicative int hashCode ()

public Final Native java.lang.Class getClass ()

publicfinalnativevoidnotify()

publicfinalnativevoidnotifyAll()


8. 最後に、これらを入れていきます。つまり、クラス

Java コード

class hello {  
    public static void main(String[] args) {  
        Class<?> demo = null;  
        try {  
            demo = Class.forName("Reflect.Person");  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        System.out.println("===============本类属性========================");  
        // 取得本类的全部属性  
        Field[] field = demo.getDeclaredFields();  
        for (int i = 0; i < field.length; i++) {  
            // 权限修饰符  
            int mo = field[i].getModifiers();  
            String priv = Modifier.toString(mo);  
            // 属性类型  
            Class<?> type = field[i].getType();  
            System.out.println(priv + " " + type.getName() + " "  
                    + field[i].getName() + ";");  
        }  
        System.out.println("===============实现的接口或者父类的属性========================");  
        // 取得实现的接口或者父类的属性  
        Field[] filed1 = demo.getFields();  
        for (int j = 0; j < filed1.length; j++) {  
            // 权限修饰符  
            int mo = filed1[j].getModifiers();  
            String priv = Modifier.toString(mo);  
            // 属性类型  
            Class<?> type = filed1[j].getType();  
            System.out.println(priv + " " + type.getName() + " "  
                    + filed1[j].getName() + ";");  
        }  
    }  
}
ログイン後にコピー

を通じてクラスのフレームワーク全体を取得します [実行結果]:

================ この属性クラス ===== ===================

プライベート java.lang.String セックス

============= ===親クラスの実装されたインターフェイスまたは属性 =======================

public static Final java.lang.String name; public static Final int age;

[ケース] 実際、リフレクションを通じて他のクラスのメソッドを呼び出すこともできます:

Java コード

class hello {  
    public static void main(String[] args) {  
        Class<?> demo = null;  
        try {  
            demo = Class.forName("Reflect.Person");  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        try{  
            //调用Person类中的sayChina方法  
            Method method=demo.getMethod("sayChina");  
            method.invoke(demo.newInstance());  
            //调用Person的sayHello方法  
            method=demo.getMethod("sayHello", String.class,int.class);  
            method.invoke(demo.newInstance(),"Rollen",20);  
               
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}
ログイン後にコピー

[実行結果]:

hello, china

Rollen 20

9. 他のクラスの set メソッドと get メソッドを呼び出す



Java コード

class hello {  
    public static void main(String[] args) {  
        Class<?> demo = null;  
        Object obj=null;  
        try {  
            demo = Class.forName("Reflect.Person");  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        try{  
         obj=demo.newInstance();  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        setter(obj,"Sex","男",String.class);  
        getter(obj,"Sex");  
    }  
   
    /** 
     * @param obj 
     *            操作的对象 
     * @param att 
     *            操作的属性 
     * */  
    public static void getter(Object obj, String att) {  
        try {  
            Method method = obj.getClass().getMethod("get" + att);  
            System.out.println(method.invoke(obj));  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
   
    /** 
     * @param obj 
     *            操作的对象 
     * @param att 
     *            操作的属性 
     * @param value 
     *            设置的值 
     * @param type 
     *            参数的属性 
     * */  
    public static void setter(Object obj, String att, Object value,  
            Class<?> type) {  
        try {  
            Method method = obj.getClass().getMethod("set" + att, type);  
            method.invoke(obj, value);  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
}// end class
ログイン後にコピー

[実行結果]:

男性


10. リフレクションによる属性の操作



Java コード

class hello {  
    public static void main(String[] args) throws Exception {  
        Class<?> demo = null;  
        Object obj = null;  
   
        demo = Class.forName("Reflect.Person");  
        obj = demo.newInstance();  
   
        Field field = demo.getDeclaredField("sex");  
        field.setAccessible(true);  
        field.set(obj, "男");  
        System.out.println(field.get(obj));  
    }  
}// end class
ログイン後にコピー

11.リフレクションによる配列情報の変更:

Javaコード

import java.lang.reflect.*;  
class hello{  
    public static void main(String[] args) {  
        int[] temp={1,2,3,4,5};  
        Class<?>demo=temp.getClass().getComponentType();  
        System.out.println("数组类型: "+demo.getName());  
        System.out.println("数组长度  "+Array.getLength(temp));  
        System.out.println("数组的第一个元素: "+Array.get(temp, 0));  
        Array.set(temp, 0, 100);  
        System.out.println("修改之后数组第一个元素为: "+Array.get(temp, 0));  
    }  
}
ログイン後にコピー

【実行結果】:

配列型: int

配列長5

配列の最初の要素: 1

変更後の配列の最初の要素は: 100

12. リフレクションによる配列サイズの変更

Java コード

class hello{  
    public static void main(String[] args) {  
        int[] temp={1,2,3,4,5,6,7,8,9};  
        int[] newTemp=(int[])arrayInc(temp,15);  
        print(newTemp);  
        System.out.println("=====================");  
        String[] atr={"a","b","c"};  
        String[] str1=(String[])arrayInc(atr,8);  
        print(str1);  
    }  
       
    /** 
     * 修改数组大小 
     * */  
    public static Object arrayInc(Object obj,int len){  
        Class<?>arr=obj.getClass().getComponentType();  
        Object newArr=Array.newInstance(arr, len);  
        int co=Array.getLength(obj);  
        System.arraycopy(obj, 0, newArr, 0, co);  
        return newArr;  
    }  
    /** 
     * 打印 
     * */  
    public static void print(Object obj){  
        Class<?>c=obj.getClass();  
        if(!c.isArray()){  
            return;  
        }  
        System.out.println("数组长度为: "+Array.getLength(obj));  
        for (int i = 0; i < Array.getLength(obj); i++) {  
            System.out.print(Array.get(obj, i)+" ");  
        }  
    }  
}
ログイン後にコピー

【运行结果】:
数组长度为: 15

1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 =====================

数组长度为: 8

a b c null null null null null

13、动态代理
   如何获得类加载器:

Java代码

class test{  
       
}  
class hello{  
    public static void main(String[] args) {  
        test t=new test();  
        System.out.println("类加载器  "+t.getClass().getClassLoader().getClass().getName());  
    }  
}
ログイン後にコピー

【程序输出】:

类加载器 sun.misc.Launcher$AppClassLoader

其实在java中有三种类类加载器。

1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。

2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类

3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。

如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。

Java代码

package Reflect;  
import java.lang.reflect.*;  
   
//定义项目接口  
interface Subject {  
    public String say(String name, int age);  
}  
   
// 定义真实项目  
class RealSubject implements Subject {  
    @Override  
    public String say(String name, int age) {  
        return name + "  " + age;  
    }  
}  
   
class MyInvocationHandler implements InvocationHandler {  
    private Object obj = null;  
   
    public Object bind(Object obj) {  
        this.obj = obj;  
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj  
                .getClass().getInterfaces(), this);  
    }  
   
    @Override  
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {  
        Object temp = method.invoke(this.obj, args);  
        return temp;  
    }  
}  
   
class hello {  
    public static void main(String[] args) {  
        MyInvocationHandler demo = new MyInvocationHandler();  
        Subject sub = (Subject) demo.bind(new RealSubject());  
        String info = sub.say("Rollen", 20);  
        System.out.println(info);  
    }  
}
ログイン後にコピー

【运行结果】:

Rollen 20

类的生命周期

在一个类编译完成之后,下一步就需要开始使用类,如果要使用一个类,肯定离不开JVM。在程序执行中JVM通过装载,链接,初始化这3个步骤完成。

类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。用来封装数据。 但是同一个类只会被类装载器装载以前

链接就是把二进制数据组装为可以运行的状态。



链接分为校验,准备,解析这3个阶段

校验一般用来确认此二进制文件是否适合当前的JVM(版本),

准备就是为静态成员分配内存空间,。并设置默认值

解析指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)

完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收。释放空间。

当没有任何引用指向Class对象时就会被卸载,结束类的生命周期

14、将反射用于工厂模式

  如果不用反射的时候,的工厂模式吧:

Java代码

/** 
 * @author Rollen-Holt 设计模式之 工厂模式 
 */  
   
interface fruit{  
    public abstract void eat();  
}  
   
class Apple implements fruit{  
    public void eat(){  
        System.out.println("Apple");  
    }  
}  
   
class Orange implements fruit{  
    public void eat(){  
        System.out.println("Orange");  
    }  
}  
   
// 构造工厂类  
// 也就是说以后如果我们在添加其他的实例的时候只需要修改工厂类就行了  
class Factory{  
    public static fruit getInstance(String fruitName){  
        fruit f=null;  
        if("Apple".equals(fruitName)){  
            f=new Apple();  
        }  
        if("Orange".equals(fruitName)){  
            f=new Orange();  
        }  
        return f;  
    }  
}  
class hello{  
    public static void main(String[] a){  
        fruit f=Factory.getInstance("Orange");  
        f.eat();  
    }  
   
}
ログイン後にコピー

这样,当我们在添加一个子类的时候,就需要修改工厂类了。如果我们添加太多的子类的时候,改的就会很多。

现在我们看看利用反射机制:

Java代码

package Reflect;  
   
interface fruit{  
    public abstract void eat();  
}  
   
class Apple implements fruit{  
    public void eat(){  
        System.out.println("Apple");  
    }  
}  
   
class Orange implements fruit{  
    public void eat(){  
        System.out.println("Orange");  
    }  
}  
   
class Factory{  
    public static fruit getInstance(String ClassName){  
        fruit f=null;  
        try{  
            f=(fruit)Class.forName(ClassName).newInstance();  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        return f;  
    }  
}  
class hello{  
    public static void main(String[] a){  
        fruit f=Factory.getInstance("Reflect.Apple");  
        if(f!=null){  
            f.eat();  
        }  
    }  
}
ログイン後にコピー

现在就算我们添加任意多个子类的时候,工厂类就不需要修改。



上面的爱吗虽然可以通过反射取得接口的实例,但是需要传入完整的包和类名。而且用户也无法知道一个接口有多少个可以使用的子类,所以我们通过属性文件的形式配置所需要的子类。

下面我们来看看: 结合属性文件的工厂模式

首先创建一个fruit.properties的资源文件,
内容为:

Java代码

apple=Reflect.Apple  
orange=Reflect.Orange
ログイン後にコピー

然后编写主类代码:

Java代码

package Reflect;  
   
import java.io.*;  
import java.util.*;  
   
interface fruit{  
    public abstract void eat();  
}  
   
class Apple implements fruit{  
    public void eat(){  
        System.out.println("Apple");  
    }  
}  
   
class Orange implements fruit{  
    public void eat(){  
        System.out.println("Orange");  
    }  
}  
   
//操作属性文件类  
class init{  
    public static Properties getPro() throws FileNotFoundException, IOException{  
        Properties pro=new Properties();  
        File f=new File("fruit.properties");  
        if(f.exists()){  
            pro.load(new FileInputStream(f));  
        }else{  
            pro.setProperty("apple", "Reflect.Apple");  
            pro.setProperty("orange", "Reflect.Orange");  
            pro.store(new FileOutputStream(f), "FRUIT CLASS");  
        }  
        return pro;  
    }  
}  
   
class Factory{  
    public static fruit getInstance(String ClassName){  
        fruit f=null;  
        try{  
            f=(fruit)Class.forName(ClassName).newInstance();  
        }catch (Exception e) {  
            e.printStackTrace();  
        }  
        return f;  
    }  
}  
class hello{  
    public static void main(String[] a) throws FileNotFoundException, IOException{  
        Properties pro=init.getPro();  
        fruit f=Factory.getInstance(pro.getProperty("apple"));  
        if(f!=null){  
            f.eat();  
        }  
    }  
}
ログイン後にコピー

【运行结果】:Apple



===========================================
实际项目中的应用:
利用java的反射机制,给两个不同的对象的属性赋值,主要是两个有相同属性的对象,类似于entity bean 和 VO 这样的POJO

Java代码

import java.lang.reflect.Field;  
import java.lang.reflect.Method;  
  
import javax.persistence.Id;  
  
import org.apache.commons.logging.Log;  
import org.apache.commons.logging.LogFactory;  
  
/** 
 * <转换对象工具> 
 * <功能详细描述> 
 * @author  zengyouyuan 
 * @version  [版本号, 2013-5-27] 
 * @see  [相关类/方法] 
 * @since  [产品/模块版本] 
 */  
public class ConvertObjectUtil  
{  
    // log  
    private static Log log = LogFactory.getLog(ConvertObjectUtil.class);  
      
    /** 
     * <两个属性相同的对象,把源对象的属性值动态赋给目标对象> 
     * <功能详细描述> 
     * @param srcClass 源类型 
     * @param srcObject 源对象 
     * @param destObject 目标对象 
     * @return 转换后的目标对象 
     * @see [类、类#方法、类#成员] 
     */  
    public static Object convert(Class<?> srcClass, Object srcObject, Object destObject)  
    {  
        Field[] srcFields = srcClass.getDeclaredFields();  
          
        int fieldCount = srcFields.length;  
       
        log.info("src class has :" + fieldCount + " fields");  
        for (int i = 0; i < fieldCount; i++)  
        {  
            // serialVersionUID和自增长的ID除外  
            if (srcFields[i].getName().equals("serialVersionUID"))  
            {  
                continue;  
            }  
              
            if (srcFields[i].getAnnotation(Id.class) != null)  
            {  
                continue;  
            }  
              
            try  
            {  
                // 利用源对象的get方法和目标对象的set方法,来给目标对象赋值  
                Method srcMethod = srcObject.getClass().getMethod("get" + uppercaseFirst(srcFields[i].getName()));  
                Object srcValue = srcMethod.invoke(srcObject);  
                  
                Method destMethod =  
                    destObject.getClass().getMethod("set" + uppercaseFirst(srcFields[i].getName()),  
                        srcFields[i].getType());  
                destMethod.invoke(destObject, srcValue);  
                  
            }  
            catch (Exception e)  
            {  
                // TODO Auto-generated catch block  
                log.error(e);  
            }  
        }  
          
        return destObject;  
    }  
      
    /** 
     * <首字母大写> 
     * <功能详细描述> 
     * @param name 
     * @return 
     * @see [类、类#方法、类#成员] 
     */  
    private static String uppercaseFirst(String name)  
    {  
        return name.substring(0, 1).toUpperCase() + name.substring(1);  
    }  
      
}
ログイン後にコピー


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート