Java 反射機制分析指南

dwd4 10年前發布 | 18K 次閱讀 Java 反射 Java開發

一、JAVA是動態語言嗎?

一般而言,說到動態言,都是指在程序運行時允許改變程序結構或者變量類型,從這個觀點看,JAVA和C++一樣,都不是動態語言。

但JAVA它卻有著一個非常突出的動態相關機制:反射。通過反射,Java可以于運行時加載、探知和使用編譯期間完全求和的類、生成其對象實體,調用其方法或者對屬性設值。所以Java算是一個半動態的語言吧。

反射的概念:

在Java中的反射機制是指在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;

對于任意一個對象,都能夠調用它的任意一個方法;

這種動態獲取信息以及動態調用對象方法的功能稱為Java語言的反射機制

二、動態性質

2.1、動態性質

  • 運行時生成對象實例;
  • 運行期間調用方法;
  • 運行時更改屬性

2.2、Java反射機制能實現的功能

  • 在運行時判斷任意一個對象所屬的類
  • 在運行時構造任意一個類的對象
  • 在運行時判斷任意懷個類所具有的方法和屬性
  • 在運行時調用任意一個對象的方法
  • 生成動態代理

2.3、Java反射應用場合

在Java程序中許多對象在運行時都會出現兩種類型:編譯時類型和運行時類型

編譯時的類型由聲明該對象時使用的類型決定,運行時的類型由實際賦給對象的類型決定

如:

Person p =new Student();
</div>

編譯時類型為Person,而運行時為Student

除此之外,程序在運行時還可能接收到外部傳入的一個對象,該對象的編譯時類型為Object,但程序又需要調用該對象運行時類型的方法。為了這些問 題程序需要在運行時發現對象和類的真實信息。然而,如果編譯時根本無法預知該對象和類可能屬于哪些類,程序只依靠運行時信息來發現該對象和類的真實信息, 此時就必須使用反射

三、Java反射API

反射API用來生成在當前JAVA虛擬機中的類、接口或者對象的信息。

  • Class類:反射的核心類,可以獲取類的屬性,方法等內容信息。
  • Field類:Java.lang.reflect.表示類的屬性,可以獲取和設置類的中屬性值。
  • Method類:Java.lang.reflect。表示類的方法,它可以用來獲取類中方法的信息或者執行方法
  • Construcor類:Java.lang.reflect。表示類的構造方法。

四、獲取全部方法和屬性

Person類

package com.pb.Reflect.classinfo;

public class Person { private String name; private String gender; private int age;

private Person() {
//
}
public Person(String name, String gender, int age) {
    super();
    this.name = name;
    this.gender = gender;
    this.age = age;
}
//getter、和setter方法
private String getName() {
    return name;
}
private void setName(String name) {
    this.name = name;
}
public String getGender() {
    return gender;
}
public void setGender(String gender) {
    this.gender = gender;
}
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}

public String toString(){
    return "姓名:"+name+"年齡: "+age;
}

}</pre> </div>

使用反射:

package com.pb.Reflect.classinfo;

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;

import javax.swing.JOptionPane;

/*

  • 通過用戶輸入類的全路徑,來獲取該類的成員方法和屬性
  • Declared獲取全部不管是私有和公有
  • 1.獲取訪問類的Class對象
  • 2.調用Class對象的方法返回訪問類的方法和屬性信息 */ public class ReflectDemo {

    /*

    • 構造方法 */ public ReflectDemo(){ //用戶輸入類的全路徑徑 //使用String組件 String classpsth=JOptionPane.showInputDialog(null,"輸入類的全路徑"); //使用Class.forName方法根據輸入的類的全路徑 返回該類的Class對象 try {
       Class cla = Class.forName(classpsth);
       //利用Class對象的cla的自審,返回方法對象集合
       Method [] method=cla.getDeclaredMethods(); //返回所有的方法
       System.out.println("========獲取方法信息============");
       for (Method meth : method) {
           //遍歷method數組,并輸出方法信息
           System.out.println(meth.toString());
       }
       System.out.println("========獲取出方法信息結束============");
       //獲取屬性利用Class對象的cla的自審,返回成員屬性對象集合
        Field [] field=cla.getDeclaredFields();
           System.out.println("========獲取成員屬性信息============");
           for (Field f : field) {
               System.out.println(f.toString());
           }
           System.out.println("========獲取成員屬性信息結束============");
       //獲取屬性利用Class對象的cla的自審,返回構造方法集合
           Constructor [] constructor=cla.getDeclaredConstructors();
           System.out.println("========獲取成員構造方法信息============");
           for (Constructor constru : constructor) {
               System.out.println(constru.toString());
           }
           System.out.println("========獲取成員構造方法信息結束============");
      
      } catch (ClassNotFoundException e) {
       e.printStackTrace();
       System.out.println("路徑輸入錯誤!");
      
      } }

}</pre> </div> </div>

package com.pb.Reflect.classinfo;

public class TestReflection {

public static void main(String[] args) {
    ReflectDemo rd=new ReflectDemo();

}

}</pre> </div>

輸入com.pb.Reflect.classinfo.Person

結果:

========獲取方法信息============
public java.lang.String com.pb.Reflect.classinfo.Person.getGender()
public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String)
public int com.pb.Reflect.classinfo.Person.getAge()
public void com.pb.Reflect.classinfo.Person.setAge(int)
public java.lang.String com.pb.Reflect.classinfo.Person.toString()
private java.lang.String com.pb.Reflect.classinfo.Person.getName()
private void com.pb.Reflect.classinfo.Person.setName(java.lang.String)
========獲取出方法信息結束============
========獲取成員屬性信息============
private java.lang.String com.pb.Reflect.classinfo.Person.name
private java.lang.String com.pb.Reflect.classinfo.Person.gender
private int com.pb.Reflect.classinfo.Person.age
========獲取成員屬性信息結束============
========獲取構造方法信息============
private com.pb.Reflect.classinfo.Person()
public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int)
========獲取構造方法信息結束============
</div>

五、使用反射的步驟

5.1、步驟

Java.lang.reflect

  • 獲得想操作類的Java.lang.Class對象
  • 調用Class的方法
  • 使用反射API來操作這些信息

 

5.2、獲取Class對象方式

  • 調用某個對象的getClass()方法

Person p = new Person();
Class cla=p.getClass();
</div>

  • 調用某個類的class屬性來獲取該類對應的Class對象

Class cls=Person.class;
</div>

  • 使用Class類的forName()靜態方法

Class cla=Class.forName(“類的全路徑”);
</div>

 六、第二種方式對象的getClass()方法

Person類,因為要聲明對象所以將構造方法public

package com.pb.Reflect.classinfo;

public class Person { private String name; private String gender; private int age;

public Person() {
//
}
public Person(String name, String gender, int age) {
    super();
    this.name = name;
    this.gender = gender;
    this.age = age;
}
//getter、和setter方法
private String getName() {
    return name;
}
private void setName(String name) {
    this.name = name;
}
public String getGender() {
    return gender;
}
public void setGender(String gender) {
    this.gender = gender;
}
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}

public String toString(){
    return "姓名:"+name+"年齡: "+age;
}

}</pre> </div>

使用反射:

package com.pb.Reflect.classinfo;

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;

import javax.swing.JOptionPane;

/*

  • 通過用戶輸入類的全路徑,來獲取該類的成員方法和屬性
  • Declared獲取全部不管是私有和公有
  • 1.獲取訪問類的Class對象
  • 2.調用Class對象的方法返回訪問類的方法和屬性信息 */

    public ReflectDemo(Person p){

     Class cla=p.getClass();
     //利用Class對象的cla的自審,返回方法對象集合
     Method [] method=cla.getDeclaredMethods(); //返回所有的方法
     System.out.println("========獲取方法信息============");
     for (Method meth : method) {
         //遍歷method數組,并輸出方法信息
         System.out.println(meth.toString());
     }
     System.out.println("========獲取出方法信息結束============");
     //獲取屬性利用Class對象的cla的自審,返回成員屬性對象集合
      Field [] field=cla.getDeclaredFields();
         System.out.println("========獲取成員屬性信息============");
         for (Field f : field) {
             System.out.println(f.toString());
         }
         System.out.println("========獲取成員屬性信息結束============");
     //獲取屬性利用Class對象的cla的自審,返回構造方法集合
         Constructor [] constructor=cla.getDeclaredConstructors();
         System.out.println("========獲取成員構造方法信息============");
         for (Constructor constru : constructor) {
             System.out.println(constru.toString());
         }
         System.out.println("========獲取成員構造方法信息結束============");
    

    }

}</pre> </div>

測試類

package com.pb.Reflect.classinfo;

public class TestReflection {

public static void main(String[] args) {
    Person p=new Person();
    ReflectDemo rd=new ReflectDemo(p);

}

}</pre> </div>

========獲取方法信息============
public java.lang.String com.pb.Reflect.classinfo.Person.getGender()
public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String)
public int com.pb.Reflect.classinfo.Person.getAge()
public void com.pb.Reflect.classinfo.Person.setAge(int)
public java.lang.String com.pb.Reflect.classinfo.Person.toString()
private java.lang.String com.pb.Reflect.classinfo.Person.getName()
private void com.pb.Reflect.classinfo.Person.setName(java.lang.String)
========獲取出方法信息結束============
========獲取成員屬性信息============
private java.lang.String com.pb.Reflect.classinfo.Person.name
private java.lang.String com.pb.Reflect.classinfo.Person.gender
private int com.pb.Reflect.classinfo.Person.age
========獲取成員屬性信息結束============
========獲取成員構造方法信息============
public com.pb.Reflect.classinfo.Person()
public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int)
========獲取成員構造方法信息結束============
</div>

七、第三種方法類的.class屬性

Person類同上

測試類:

package com.pb.Reflect.classinfo;

import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;

public class TestReflection {

public static void main(String[] args) {
    /*第二種方法
    Person p=new Person();
    ReflectDemo rd=new ReflectDemo(p);

*/

    /*
     * 第三種方式.class屬性
     */
    Class cla=Person.class;
    //利用Class對象的cla的自審,返回方法對象集合
            Method [] method=cla.getDeclaredMethods(); //返回所有的方法
            System.out.println("========獲取方法信息============");
            for (Method meth : method) {
                //遍歷method數組,并輸出方法信息
                System.out.println(meth.toString());
            }
            System.out.println("========獲取出方法信息結束============");
            //獲取屬性利用Class對象的cla的自審,返回成員屬性對象集合
             Field [] field=cla.getDeclaredFields();
                System.out.println("========獲取成員屬性信息============");
                for (Field f : field) {
                    System.out.println(f.toString());
                }
                System.out.println("========獲取成員屬性信息結束============");
            //獲取屬性利用Class對象的cla的自審,返回構造方法集合
                Constructor [] constructor=cla.getDeclaredConstructors();
                System.out.println("========獲取成員構造方法信息============");
                for (Constructor constru : constructor) {
                    System.out.println(constru.toString());
                }
                System.out.println("========獲取成員構造方法信息結束============");
}

}</pre> </div>

結果:

同上

========獲取方法信息============
public java.lang.String com.pb.Reflect.classinfo.Person.getGender()
public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String)
public int com.pb.Reflect.classinfo.Person.getAge()
public void com.pb.Reflect.classinfo.Person.setAge(int)
public java.lang.String com.pb.Reflect.classinfo.Person.toString()
private java.lang.String com.pb.Reflect.classinfo.Person.getName()
private void com.pb.Reflect.classinfo.Person.setName(java.lang.String)
========獲取出方法信息結束============
========獲取成員屬性信息============
private java.lang.String com.pb.Reflect.classinfo.Person.name
private java.lang.String com.pb.Reflect.classinfo.Person.gender
private int com.pb.Reflect.classinfo.Person.age
========獲取成員屬性信息結束============
========獲取成員構造方法信息============
public com.pb.Reflect.classinfo.Person()
public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int)
========獲取成員構造方法信息結束============
</div> 來源:森林森

 本文由用戶 dwd4 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!