### 為什么寫這篇文章
reflect是java的一個關鍵技術,以前,我也只是零星的知道一些點,也會幾下三腳貓的reflect使用,但是沒有系統的掌握此知識點。
正好這二天看到CSDN學院中有一個宋紅康老師的視頻–<<[java基礎核心技術:Java反射機制(day19-day20)](http://edu.csdn.net/course/detail/809)>>,看完之后受益匪淺啊(點個贊),如果你對reflect不熟,強烈建議大家好好的看看。
看完視頻后,我花了點時間,也是參考此視頻寫了一個Demo,相信應該在此Demo中把reflect系統的學習。
### reflect的幾個關鍵點
reflect是java的反射機制,功能十分強大。
### 關鍵一:包java.lang.reflect
在java的java.lang.reflect包中提供了對該功能的支持。
我可以查看java.lang.reflect包,可以看到下面幾個關鍵的類:
| 關鍵類 | 說明 |
|-----|-----|
| Constructor-構造類 | This class represents a constructor. |
| Field-屬性類 | This class represents a field. |
| Method-方法類 | This class represents a method. |
| Modifier-修飾符類 | This class provides static methods to decode class and member modifiers. |
### 關鍵二:類java.lang.Class
而reflect的源頭是java.lang.Class類,Class類是reflect的總導演,所有java類都繼承Object類,在Object類中有getClass()方法,該方法返回一個類型為Class的對象。如代碼:
~~~
Class c = persion.getClass();//persion為類Persion的一個對象
~~~
java.lang.Class類的幾個關鍵方法:
| 關鍵方法 | 說明 |
|-----|-----|
| getPackage() | 返回包的路徑 |
| getName() | 返回類的名稱 |
| getSuperclass() | 返回父類 |
| getInterfaces() | 返回其實現的接口 |
| getConstructors() | 返回其所有的public構造方法 |
| getConstructors(Class… parameterTypes) | 返回其指定參數的public構造方法 |
| getDeclaredConstructors() | 返回其所有聲明的構造方法,包括private構造方法 |
| getDeclaredConstructors(Class… parameterTypes) | 返回其指定參數的構造方法,包括private構造方法 |
| getMethods() | 返回其所有的public的方法,包括其父類的public方法 |
| getMethod(String name, Class… parameterTypes) | 返回其指定的public的方法 |
| getDeclaredFields() | 返回其聲明的所有的方法,包括private類型的方法 |
| getDeclaredMethod(String name, Class… parameterTypes) | 返回其指定參數的方法,包括private類型的方法 |
| getFields() | 返回其所有的public屬性,包括其父類的public屬性 |
| getField(String name) | 返回其指定的public屬性,包括其父類的public屬性 |
| getDeclaredFields() | 返回其聲明的所有的屬性,包括其private類型的屬性 |
| getDeclaredField(String name) | 返回其指定的屬性,包括其private類型的屬性 |
| getClasses() | 返回其public的內部類 |
| getDeclaredClasses() | 返回其所有的內部類,包括private類型的內部類 |
### 關鍵三:類Constructor
—–java.lang.reflect.Constructor
訪問指定的構造方法,需要根據該構造方法的入口參數的類型來訪問。如:
~~~
c.getDeclaredConstructor(String.class,int.class);
c.getDeclaredConstructor(new Class[]{String.class,int.class});
~~~
Constructor類的常用方法:
| 關鍵方法 | 說明 |
|-----|-----|
| isVarArgs() | 查看該構造方法是否帶有可變數量的參數 |
| getParameterTypes() | 返回構造方法的參數列表 |
| getExceptionTypes() | 返回構造方法的異常列表 |
| newInstance(Object… args) | 返回該構造方法創建的類的對象 |
| setAccessible(boolean flag) | 讓private類型的構造方法可以創建類的對象 |
| getModifiers() | 返回構造方法的類型 |
### 關鍵四:類Field
—–java.lang.reflect.Field
訪問指定的屬性,需要根據該屬性的名稱來訪問。如:
~~~
c.getDeclaredField("name_field");
~~~
Field類的常用方法:
| 關鍵方法 | 說明 |
|-----|-----|
| getName() | 返回成員變量的名稱 |
| getType() | 返回成員變量的類型 |
| get(Object object) | 返回指定對象object的成員變量的值 |
| set(Object object, Object value) | 給指定對象object的成員變量設置value值 |
| setAccessible(boolean flag) | 讓private類型的成員變量擁有public權限 |
| getModifiers() | 返回成員變量的類型 |
### 關鍵五:類Method
—– java.lang.reflect.Method
訪問指定的方法,需要根據該方法的名稱和入口參數的類型來訪問。如:
~~~
c.getDeclaredMethod("method_name",String.class,int.class);
c.getDeclaredMethod("method_name",new Class[]{String.class,int.class});
~~~
Method類的常用方法:
| 關鍵方法 | 說明 |
|-----|-----|
| getName() | 返回該方法的名稱 |
| getParameterTypes() | 返回方法的參數列表 |
| getReturnType() | 返回該方法的返回值類型 |
| getExceptionTypes() | 返回方法的異常列表 |
| getModifiers() | 返回方法的類型 |
| isVarArgs() | 查看該方法是否帶有可變數量的參數 |
| invoke(Object receiver, Object… args) | 用入口參數來調用指定對象的方法 |
| setAccessible(boolean flag) | 讓private類型的方法擁有public權限 |
### reflect的作用
- 在運行時判斷任意一個對象所屬的類
- 在運行時構造任意一個類的對象
- 在運行時判斷任意一個類的完整結構
如屬性,方法,構造方法,父類等等
- 在運行時調用任意一個類的對象的屬性和方法
- 生成動態代理
### reflect的詳細使用指南
### 創建對應的Class實例
java.lang.Class 反射的源頭,反射涉及到的類都在java.lang.reflect目錄下,如Field,Method,ConstructorType等等。
實例化Class的方法(4種方法):
- 調用運行時類的.class屬性
~~~
c = Persion.class;
System.out.println("方法一 : 調用運行時類的.class屬性: "+c.toString());
~~~
- 通過運行時類的對象,調用getClass()方法
~~~
c = persion.getClass();
System.out.println("方法二 : 通過運行時類的對象,調用getClass()方法: "+c.toString());
~~~
- 調用Class的靜態方法forName(String className)
~~~
c = Class.forName(Persion.class.getName().toString());
System.out.println("方法三 : 調用Class的靜態方法forName(String className): "+c.toString());
~~~
- 通過類的加載器
~~~
//ClassLoader classLoader = this.getClass().getClassLoader();
ClassLoader classLoader = Persion.class.getClassLoader();
c = classLoader.loadClass(className);
System.out.println("方法四:通過類的加載器: "+c.toString());
~~~
### 有了Class實例之后,可以做什么?
- 可以創建對應的運行時類的對象
方法一:調用Class的newInstance方法
方法二:調用指定的構造器創建運行時類的對象
- 可以獲取對應的運行時類的完整結構
如屬性,方法,構造方法,包,父類,接口,內部類等等
- 可以調用對應的運行時類的指定結構
(如指定的屬性,方法,構造方法)
- 動態代碼
反射的應用,體會反射的動態性。
### 這個Demo如何一一破解reflect的關鍵點
### Demo的幾個相關類
在這個Demo中,我們定義一個Creature 類,類中定義了一個public類型的變量weight和private類型的變量color,一個內部類InnerCreature。
~~~
package com.java.reflect.demo;
public class Creature {
public int weight;
private int color;
@Override
public String toString() {
return "Creature [weight=" + weight + ", color=" + color + "]";
}
public Creature(){
super();
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
private int getColor() {
return color;
}
private void setColor(int color) {
this.color = color;
}
//內部類
public class InnerCreature{
}
}
~~~
再定義一個接口ISpeakLister :
~~~
package com.java.reflect.demo;
public interface ISpeakLister {
public void speak(String talk);
}
~~~
定義一個Person類:
這個類非常簡單,其父類是Creature,實現了ISpeakLister和Serializable接口,包括了public類型的,private類型的,static類型的屬性,public和private類型的構造方法,public,static和private類型的方法,public和private類型的內部類。
~~~
package com.java.reflect.demo;
import java.io.Serializable;
public class Person extends Creature implements ISpeakLister,Serializable{
private String name;
private int age;
public int id;
public static String weather = "今天天氣好晴朗!!";
public Person(){
super();
System.out.println("Person--Person()");
}
public Person(String name,int age,int id){
super();
this.name = name;
this.age = age;
this.id = id;
System.out.println("Person--Person(String name,int age,int id)");
}
private Person(String name){
super();
this.name = name;
}
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public static void showWeather(){
System.out.println("weather: "+ weather);
}
@Override
public String toString() {
return "Persion [name=" + name + ", age=" + age + ", id=" + id +",weather="+weather+ "]---"+super.toString();
}
@Override
public void speak(String talk) {
// TODO Auto-generated method stub
System.out.println("talk: "+ talk);
}
//inner class
public class innerClass {
}
private class innerPriClass{
}
}
~~~
### reflect的使用
reflect使用,需要對應的Class對象,對應的類的對象,為了方便,我們定義一個變量保存類的類名。
### 定義Class變量c,Person對象person和類名:
~~~
private static Class c;
private static Person person = new Person();
private static String className = "com.java.reflect.demo.Person";
~~~
### 實例化Class的方法(4種方法)
~~~
//實例化Class的方法(4種方法):
//java.lang.Class 反射的源頭
public static void createClass() throws ClassNotFoundException{
System.out.println(" ");
System.out.println("createClass()");
//方法一 : 調用運行時類的.class屬性
c = Person.class;
System.out.println("方法一 : 調用運行時類的.class屬性: "+c.toString());
//方法二 : 通過運行時類的對象,調用getClass()方法
c = person.getClass();
System.out.println("方法二 : 通過運行時類的對象,調用getClass()方法: "+c.toString());
//方法三 : 調用Class的靜態方法forName(String className)
c = Class.forName(Person.class.getName().toString());
//c = Class.forName(className);
System.out.println("方法三 : 調用Class的靜態方法forName(String className): "+c.toString());
//方法四:通過類的加載器
// ClassLoader classLoader = this.getClass().getClassLoader();
ClassLoader classLoader = Person.class.getClassLoader();
c = classLoader.loadClass(className);
System.out.println("方法四:通過類的加載器: "+c.toString());
}
~~~
對應的輸出信息:
~~~
createClass()
方法一 : 調用運行時類的.class屬性: class com.java.reflect.demo.Person
方法二 : 通過運行時類的對象,調用getClass()方法: class com.java.reflect.demo.Person
方法三 : 調用Class的靜態方法forName(String className): class com.java.reflect.demo.Person
方法四:通過類的加載器: class com.java.reflect.demo.Person
~~~
### 創建對應的運行時類的對象
~~~
//創建對應的運行時類的對象
public static void createInstance(Class c) throws Exception{
//方法一:調用Class的newInstance方法創建運行時類的對象
System.out.println(" ");
System.out.println("createInstance()");
person = (Person)c.newInstance();
System.out.println("方法一:調用Class的newInstance方法創建運行時類的對象 --person: "+person);
//方法二:調用指定的構造器創建運行時類的對象
//我們指定public類型的構造方法Person(String name,int age,int id)來創建對象
Constructor constructor = c.getDeclaredConstructor(String.class,int.class,int.class);
person = (Person) constructor.newInstance("xxx",10,1);
System.out.println("方法二:調用指定的構造器(public)創建運行時類的對象 --person: "+person);
//我們指定private類型的構造方法Person(String name)來創建對象
constructor = c.getDeclaredConstructor(String.class);
constructor.setAccessible(true);
person = (Person) constructor.newInstance("****");
System.out.println("方法二:調用指定的構造器(private)創建運行時類的對象 --person: "+person);
}
~~~
輸出信息:
~~~
createInstance()
Person--Person()
方法一:調用Class的newInstance方法創建運行時類的對象 --person: Persion [name=null, age=0, id=0,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
Person--Person(String name,int age,int id)
方法二:調用指定的構造器(public)創建運行時類的對象 --person: Persion [name=xxx, age=10, id=1,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
方法二:調用指定的構造器(private)創建運行時類的對象 --person: Persion [name=****, age=0, id=0,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
~~~
輸出信息分析:
我們調用Class類的newInstance(),會直接調用Class類的無參構造方法來生成類的對象,也可以調用Class類的getDeclaredConstructor方法來獲取Class類的指定構造方法,再調用Constructor類的newInstance方法來生成類的對象。
### 獲取對應的運行時類的完整結構
#### 獲取類的構造方法
~~~
private static void getConstructs(Class c) {
// TODO Auto-generated method stub
System.out.println(" ");
System.out.println("getConstructs");
//getConstructors 此方法為獲取類的public的構造方法
System.out.println("getConstructors為獲取類的public的構造方法 ");
Constructor[] constructors1 = c.getConstructors();
for(int i=0;i<constructors1.length;i++){
System.out.println("constructors ["+i+"] :"+constructors1[i]);
}
//getDeclaredConstructors為獲取類本身自己定義的所有構造方法
System.out.println("getDeclaredConstructors此方法為獲取類本身自己定義的所有構造方法 ");
Constructor[] constructors2 = c.getDeclaredConstructors();
for(int i=0;i<constructors2.length;i++){
System.out.println("constructors ["+i+"] :"+constructors2[i]);
}
}
~~~
輸出信息:
~~~
getConstructs
getConstructors 此方法為獲取類的public的構造方法
constructors [0] :public com.java.reflect.demo.Person()
constructors [1] :public com.java.reflect.demo.Person(java.lang.String,int,int)
getDeclaredConstructors 此方法為獲取類本身自己定義的所有構造方法
constructors [0] :public com.java.reflect.demo.Person()
constructors [1] :private com.java.reflect.demo.Person(java.lang.String)
constructors [2] :public com.java.reflect.demo.Person(java.lang.String,int,int)
~~~
#### 獲取類的方法
~~~
//獲取類的方法
private static void getMethods(Class c) {
// TODO Auto-generated method stub
System.out.println(" ");
System.out.println("getMethods");
//getMethods 此方法為獲取類的public方法,包括父類的public方法
System.out.println("getMethods 此方法為獲取類的public方法,包括父類的public方法 ");
Method[] method1 = c.getMethods();
for(int i=0;i<method1.length;i++){
System.out.println("method1 ["+i+"] :"+method1[i]);
}
//getDeclaredMethods 此方法為獲取類本身聲明的所有方法,包括private
System.out.println(" ");
System.out.println("getDeclaredMethods 此方法為獲取類本身聲明的所有方法,包括private ");
Method[] method2 = c.getDeclaredMethods();
for(int i=0;i<method2.length;i++){
System.out.println("method2 ["+i+"] :"+method2[i]);
}
}
~~~
輸出信息:
~~~
getMethods
getMethods 此方法為獲取類的public方法,包括父類的public方法
method1 [0] :public void com.java.reflect.demo.Person.setAge(int)
method1 [1] :public static void com.java.reflect.demo.Person.showWeather()
method1 [2] :public int com.java.reflect.demo.Person.getAge()
method1 [3] :public void com.java.reflect.demo.Person.setId(int)
method1 [4] :public void com.java.reflect.demo.Person.speak(java.lang.String)
method1 [5] :public java.lang.String com.java.reflect.demo.Person.toString()
method1 [6] :public int com.java.reflect.demo.Person.getId()
method1 [7] :public int com.java.reflect.demo.Creature.getWeight()
method1 [8] :public void com.java.reflect.demo.Creature.setWeight(int)
method1 [9] :public final native java.lang.Class java.lang.Object.getClass()
method1 [10] :public native int java.lang.Object.hashCode()
method1 [11] :public boolean java.lang.Object.equals(java.lang.Object)
method1 [12] :public final native void java.lang.Object.notify()
method1 [13] :public final native void java.lang.Object.notifyAll()
method1 [14] :public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
method1 [15] :public final void java.lang.Object.wait() throws java.lang.InterruptedException
method1 [16] :public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
getDeclaredMethods 此方法為獲取類本身聲明的所有方法,包括private
method2 [0] :public void com.java.reflect.demo.Person.setAge(int)
method2 [1] :public static void com.java.reflect.demo.Person.showWeather()
method2 [2] :public int com.java.reflect.demo.Person.getAge()
method2 [3] :public void com.java.reflect.demo.Person.setId(int)
method2 [4] :public void com.java.reflect.demo.Person.speak(java.lang.String)
method2 [5] :public java.lang.String com.java.reflect.demo.Person.toString()
method2 [6] :private java.lang.String com.java.reflect.demo.Person.getName()
method2 [7] :public int com.java.reflect.demo.Person.getId()
method2 [8] :private void com.java.reflect.demo.Person.setName(java.lang.String)
~~~
#### 獲取類的屬性
~~~
//獲取類的屬性
private static void GetFields(Class c) {
// TODO Auto-generated method stub
System.out.println(" ");
System.out.println("GetFields");
//getFields 此方法為獲取類的public屬性,包括父類的public屬性
System.out.println("getFields 此方法為獲取類的public屬性,包括父類的public屬性 ");
Field[] field1 = c.getFields();
for(int i=0;i<field1.length;i++){
System.out.println("field1 ["+i+"] :"+field1[i]);
}
System.out.println(" ");
//getDeclaredFields 此方法為獲取類的本身聲明的所有屬性,包括private
System.out.println("getDeclaredFields 此方法為獲取類的本身聲明的所有屬性,包括private ");
Field[] field2 = c.getDeclaredFields();
for(int i=0;i<field2.length;i++){
System.out.println("field2 ["+i+"] :"+field2[i]);
}
}
~~~
信息輸出:
~~~
GetFields
getFields 此方法為獲取類的public屬性,包括父類的public屬性
field1 [0] :public int com.java.reflect.demo.Person.id
field1 [1] :public static java.lang.String com.java.reflect.demo.Person.weather
field1 [2] :public int com.java.reflect.demo.Creature.weight
getDeclaredFields 此方法為獲取類的本身聲明的所有屬性,包括private
field2 [0] :private java.lang.String com.java.reflect.demo.Person.name
field2 [1] :private int com.java.reflect.demo.Person.age
field2 [2] :public int com.java.reflect.demo.Person.id
~~~
#### 獲取類的其它信息
如包,父類,接口,內部類等等
~~~
//獲取類的其它信息,如包,父類,接口,內部類等等
private static void getClassOtherInfo(Class c) {
// TODO Auto-generated method stub
System.out.println(" ");
System.out.println("getClassOtherInfo");
//獲取類的包
String p = c.getPackage().toString();
System.out.println("類的包名:"+p);
//獲取類的父類
Class parentClass = c.getSuperclass();
System.out.println("類的父類:"+parentClass.getName());
//獲取類的接口
Class[] interfaces =c.getInterfaces();
if(interfaces.length >0){
System.out.println("類的接口:");
for(int i=0;i<interfaces.length;i++){
System.out.println("interfaces["+i+"] :"+interfaces[i]);
}
}
//獲取類的內部類
//getDeclaredClasses方法獲取類本身定義的所有內部類,包括private
Class[] innerClass1 =c.getDeclaredClasses();
if(innerClass1.length >0){
System.out.println("類的所有內部類 ,包括private:");
for(int i=0;i<innerClass1.length;i++){
System.out.println("innerClass1["+i+"] :"+innerClass1[i]);
}
}
//同理getClasses方法獲取類的public內部類,包括父類的public內部類
Class[] innerClass2 =c.getClasses();
if(innerClass2.length >0){
System.out.println("類的public內部類,包括父類的public內部類:");
for(int i=0;i<innerClass2.length;i++){
System.out.println("innerClass2["+i+"] :"+innerClass2[i]);
}
}
}
~~~
輸出信息:
~~~
getClassOtherInfo
類的包名:package com.java.reflect.demo
類的父類:com.java.reflect.demo.Creature
類的接口:
interfaces[0] :interface com.java.reflect.demo.ISpeakLister
interfaces[1] :interface java.io.Serializable
類的所有內部類 ,包括private:
innerClass1[0] :class com.java.reflect.demo.Person$innerClass
innerClass1[1] :class com.java.reflect.demo.Person$innerPriClass
類的public內部類,包括父類的public內部類:
innerClass2[0] :class com.java.reflect.demo.Person$innerClass
innerClass2[1] :class com.java.reflect.demo.Creature$InnerCreature
~~~
### 對類的對象的指定方法,屬性,構造方法進行操作
#### 對指定構造方法進行操作
~~~
//2.3.1 對指定構造方法進行操作
private static void callConstruct(Class c) throws Exception {
// TODO Auto-generated method stub
System.out.println(" ");
System.out.println("callConstruct");
//對private類型的構造方法進行操作
Constructor constructor1 = c.getDeclaredConstructor(String.class);
constructor1.setAccessible(true);
person = (Person)constructor1.newInstance("zsmj");
System.out.println("person:"+person);
//對public類型的構造方法進行操作
Constructor constructor2 = c.getDeclaredConstructor(String.class,int.class,int.class);
//constructor2.setAccessible(true);
person = (Person)constructor2.newInstance("yyf",10,2);
System.out.println("person:"+person);
}
~~~
輸出信息:
~~~
callConstruct
person:Persion [name=zsmj, age=0, id=0,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
Person--Person(String name,int age,int id)
person:Persion [name=yyf, age=10, id=2,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
~~~
#### 對指定方法進行操作
~~~
//2.3.2 對指定方法進行操作
private static void callMethod(Class c) throws Exception {
// TODO Auto-generated method stub
System.out.println(" ");
System.out.println("callMethod");
//1.對private類型的方法進行操作
//getDeclaredMethod 方法獲取類本身聲明的方法,包括private類型的方法
System.out.println("getDeclaredMethod 方法獲取類本身聲明的方法,包括private類型的方法,以setName方法為例:");
Method m1 = c.getDeclaredMethod("setName", String.class);
m1.setAccessible(true);
System.out.println("修改前的person:"+person);
m1.invoke(person, "yyf_01");
System.out.println("修改后的person:"+person);
//2.對public類型的方法進行操作,包括父類的方法
//getMethod 對public類型的方法進行操作,包括父類的方法
//2.1 以運行類的本身聲明的public類型的setAge方法為例
System.out.println("getMethod 對public類型的方法進行操作,包括父類的方法,以類本身的setAge方法為例:");
Method m2 = c.getMethod("setAge", int.class);
System.out.println("修改前的person:"+person);
m2.invoke(person, 11);
System.out.println("修改后的person:"+person);
//2.2 以運行類的父類聲明的public類型的setWeight方法為例
System.out.println("getMethod 對public類型的方法進行操作,包括父類的方法,以父類的setWeight方法為例:");
Method m3 = c.getMethod("setWeight", int.class);
System.out.println("修改前的person:"+person);
m3.invoke(person, 100);
System.out.println("修改后的person:"+person);
//3.對static類型的方法進行操作,以類本身的showWeather靜態方法為例
System.out.println("getMethod 對public類型的方法進行操作,包括父類的方法,以父類的showWeather方法為例:");
Method m4 = c.getMethod("showWeather");
m4.invoke(null);
//4 獲取指定方法的返回值,以類本身的private類型的getName方法為例
System.out.println("獲取指定方法的返回值,以類本身的private類型的getName方法為例:");
Method m5 = c.getDeclaredMethod("getName");
m5.setAccessible(true);
String name = (String)m5.invoke(person);
System.out.println("name:"+name);
}
~~~
輸出信息:
~~~
callMethod
getDeclaredMethod 方法獲取類本身聲明的方法,包括private類型的方法,以setName方法為例:
修改前的person:Persion [name=yyf, age=10, id=2,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
修改后的person:Persion [name=yyf_01, age=10, id=2,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
getMethod 對public類型的方法進行操作,包括父類的方法,以類本身的setAge方法為例:
修改前的person:Persion [name=yyf_01, age=10, id=2,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
修改后的person:Persion [name=yyf_01, age=11, id=2,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
getMethod 對public類型的方法進行操作,包括父類的方法,以父類的setWeight方法為例:
修改前的person:Persion [name=yyf_01, age=11, id=2,weather=今天天氣好晴朗!!]---Creature [weight=0, color=0]
修改后的person:Persion [name=yyf_01, age=11, id=2,weather=今天天氣好晴朗!!]---Creature [weight=100, color=0]
getMethod 對public類型的方法進行操作,包括父類的方法,以父類的showWeather方法為例:
weather: 今天天氣好晴朗!!
獲取指定方法的返回值,以類本身的private類型的getName方法為例:
name:yyf_01
~~~
#### 對指定屬性進行操作
~~~
//2.3.3 對指定屬性進行操作
private static void callField(Class c) throws Exception {
// TODO Auto-generated method stub
System.out.println(" ");
System.out.println("callField");
//1.對public類型的屬性進行操作,以類本身的public屬性id為例:
System.out.println("對public類型的屬性進行操作,以類本身的public屬性id為例");
Field f1 = c.getField("id");
int id = (int)f1.get(person);
System.out.println("修改前person對象的id="+id);
f1.set(person, 3);
id = (int)f1.get(person);
System.out.println("修改后person對象的id="+id);
//2.對private類型的屬性進行操作,以類本身的private屬性age為例:
System.out.println("對private類型的屬性進行操作,以類本身的private屬性age為例:");
Field f2 = c.getDeclaredField("age");
f2.setAccessible(true);
int age = (int)f2.get(person);
System.out.println("修改前person對象的age="+age);
f2.set(person, 12);
age = (int)f2.get(person);
System.out.println("修改后person對象的age="+age);
//3.對static類型的屬性進行操作,以類本身的static屬性weather為例:
System.out.println("對static類型的屬性進行操作,以類本身的static屬性weather為例:");
Field f3 = c.getDeclaredField("weather");
f3.setAccessible(true);
String weather = (String)f3.get(person);
System.out.println("修改前person對象的weather="+weather);
//f3.set(person, "今天天氣好涼爽!!");
f3.set(null, "今天天氣好涼爽!!");
weather = (String)f3.get(person);
System.out.println("修改后person對象的weather="+weather);
}
~~~
輸出信息:
~~~
callField
對public類型的屬性進行操作,以類本身的public屬性id為例
修改前person對象的id=2
修改后person對象的id=3
對private類型的屬性進行操作,以類本身的private屬性age為例:
修改前person對象的age=11
修改后person對象的age=12
對static類型的屬性進行操作,以類本身的static屬性weather為例:
修改前person對象的weather=今天天氣好晴朗!!
修改后person對象的weather=今天天氣好涼爽!!
~~~
### 源碼下載地址
[http://download.csdn.net/detail/hfreeman2008/9175627](http://download.csdn.net/detail/hfreeman2008/9175627)
參考資料:
1.Java基礎核心技術:Java反射機制(day19-day20)
[http://edu.csdn.net/course/detail/809](http://edu.csdn.net/course/detail/809)
- 前言
- Java核心技術之Comparator和Comparable在排序中的應用
- Java核心技術之容器
- Java核心技術之基本數據類型
- java核心技術之正則表達式
- java核心技術之reflect(一):一個系統學習reflect的Demo(精)
- java核心技術之IO流(一)File類
- java核心技術之IO流(二)FileInputStream和FileOutputStream
- java核心技術之IO流(三)FileReader和FileWriter
- java核心技術之IO流(四)BufferedInputStream和BufferedOutputStream
- java核心技術之IO流(五)BufferedReader和BufferedWriter
- java核心技術之IO流(六)DataInputStream和DataOutputStream