Java反射機制分析指南

Java反射機制分析指南

2015-05-09 程序猿

一、JAVA是動態語言嗎?


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


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


反射的概念:


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


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


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


二、動態性質


2.1、動態性質


●運行時生成對象實例;

●運行期間調用方法;

●運行時更改屬性


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


●在運行時判斷任意一個對象所屬的類

●在運行時構造任意一個類的對象

●在運行時判斷任意懷個類所具有的方法和屬性

●在運行時調用任意一個對象的方法

●生成動態代理


2.3、Java反射應用場合


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


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


如:

Person p =new Student();

編譯時類型爲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;

}


}

使用反射:

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("路徑輸入錯誤!");

}

}


}

package com.pb.Reflect.classinfo;


public class TestReflection {


public static void main(String[] args) {

ReflectDemo rd=new ReflectDemo();


}


}

輸入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)

========獲取構造方法信息結束============


五、使用反射的步驟


5.1、步驟


Java.lang.reflect


●獲得想操作類的Java.lang.Class對象

●調用Class的方法

●使用反射API來操作這些信息


5.2、獲取Class對象方式


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

Person p = new Person();

Class cla=p.getClass();

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

Class cls=Person.class;

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

Class cla=Class.forName(“類的全路徑”);

六、第二種方式對象的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;

}


}

使用反射:

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("========獲取成員構造方法信息結束============");

}


}

測試類

package com.pb.Reflect.classinfo;


public class TestReflection {


public static void main(String[] args) {

Person p=new Person();

ReflectDemo rd=new ReflectDemo(p);


}


}

========獲取方法信息============

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)

========獲取成員構造方法信息結束============

七、第三種方法類的.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("========獲取成員構造方法信息結束============");

}


}

結果:


同上

========獲取方法信息============

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)

========獲取成員構造方法信息結束============


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章