在我們生活中,車上或者路上有時候會遇到一種很討厭的人——“小偷”,趁我們不注意或者疏忽的時候拿走屬於我們的東西。更有甚者,趁我們不在家的時候,手持一把萬能鑰匙,打開我們的房門,悠閒的查看房間的布置,翻找著他們需要的東西,惬意的時候也許會躺在客廳的沙發上,喝著冰箱裡的飲料,俨然一副真正主人的樣子。在JAVA中就有這樣一個存在——“反射”,這是JDK提供的一把萬能鑰匙,任何人都可以使用它來獲取本不應該屬於自己的東西。
在剛學習JAVA的時候,我們就知道,JAVA提供了private,protected,public,default四種修飾符,這四種修飾符象征著我們的使用權限。就好像我們的房子,房子是我們自己的,但是可以被子孫們繼承,因此,房子可以被修飾為protected。房子裡有的東西是我私人的,只屬於我自己,誰都不能用,這可以被修飾為private。當然有的東西,親戚朋友來了,都可以用,可以吃,那麼可以被定義為default。看門外沒有垃圾桶,個人本著愛護環境的初衷,放了一個垃圾桶在外面,誰都可以用,垃圾桶自己就可以被修飾為public。但是“小偷”就是沒有這種限制,管你東西是不是私人的,他仗著手上的萬能鑰匙就是可以把這種訪問權限糟蹋掉。尤其這把鑰匙還是JDK出品的,很無奈!
那下面就看看JDK提供的這把萬能鑰匙到底能干些什麼吧。
1、創建House類,代碼如下:
package person.lb.reflect; /** * 房子 * @author noboudns * */ public class House { //擁有者 private String owner = "nobounds"; //房間數 private int roomNum = 3; //垃圾桶 public String dustbin = "垃圾桶"; public String getDustbin() { return dustbin; } private void turnOnTV() { System.out.println("打開電視……"); } }
2、創建KeyDemo 類,代碼如下:
package person.lb.reflect; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class KeyDemo { public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException, ClassNotFoundException, SecurityException, NoSuchFieldException { Class<?> clazz = Class.forName("person.lb.reflect.House"); String className = clazz.getName(); System.out.println("戶主是:" + className); Field[] fields = clazz.getDeclaredFields(); System.out.println("看看家裡都有什麼東西:"); for(Field field : fields ) { System.out.println("類型:" + field.getType() + ",名稱:" + field.getName() + ",使用權限:" + Modifier.toString(field.getModifiers())); } System.out.println("再看看家裡有什麼好玩的:"); Method[] methods = clazz.getDeclaredMethods(); for(Method method : methods) { System.out.println("名字:" + method.getName() + ",需要的東西:" + method.getParameterTypes().toString() + ",得到什麼:" + method.getReturnType().toString()); System.out.println("用用看效果怎麼樣,嘿嘿!"); //設置為可訪問的 method.setAccessible(true); method.invoke(clazz.newInstance()); } System.out.println("心情不錯,把房子據為己有吧!"); House house = (House) clazz.newInstance(); Field field = clazz.getDeclaredField("ownerName"); field.setAccessible(true); field.set(house, "thief"); System.out.println("現在房子的主人是:" + house.getOwnerName() ); } }
結果為:
戶主是:person.lb.reflect.House 看看家裡都有什麼東西: 類型:class java.lang.String,名稱:ownerName,使用權限:private 類型:int,名稱:roomNum,使用權限:private 類型:class java.lang.String,名稱:dustbin,使用權限:public 再看看家裡有什麼好玩的: 名字:getOwnerName,需要的東西:[Ljava.lang.Class;@3d4b7453,得到什麼:class java.lang.String 用用看效果怎麼樣,嘿嘿! 名字:getDustbin,需要的東西:[Ljava.lang.Class;@1cc2ea3f,得到什麼:class java.lang.String 用用看效果怎麼樣,嘿嘿! 名字:turnOnTV,需要的東西:[Ljava.lang.Class;@40a0dcd9,得到什麼:void 用用看效果怎麼樣,嘿嘿! 打開電視…… 心情不錯,把房子據為己有吧! 現在房子的主人是:thief
當然了,JDK中不止提供了這麼多功能,如果有興趣可以自己私下去查找相關資料,本文就不多說什麼了。