Java之反射和動態(tài)代理

1. 反射

反射就是根據(jù)類名去獲取類的成員、構(gòu)造方法允蜈、方法冤吨、實現(xiàn)的接口、繼承的父類等

測試代碼:先建一個Person類陷寝,要有有參構(gòu)造函數(shù)锅很,箜參構(gòu)造函數(shù),私有公有成員凤跑,私有公有方法爆安,toString方法

public class Person {

????public String name = null;

????private int age = 0;

????public Person() {

????????name = "kluter";

????????age = 34;

????}

????public Person(String name, int age){

????????this.name = name;

????????this.age = age;

????}

????private Person(String name){

????????this.name = name;

????}

????@Override

????public String toString() {

????????return "Person [name=" + name + ", age=" + age + "]";

????}

????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;

????}

????private void getSth(String testStr){

????????out.println(testStr);

????}

}

創(chuàng)建測試主程序:

import java.lang.reflect.Constructor;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

public class MyReflect {

????public String className = null;

????public Class personClass = null;

????/**

????* reflect Person class

????* @throws Exception

????*/

????public void init() throws Exception {

????????className = "com.gamebear.reflect.Person";

????????personClass = Class.forName(className);

????}

????/**

????* get a class object by reflect

????*/

????public void getClassName(){

????????out.println(personClass);

????}

????/**

????* get a class object by Class

????*/

????public void getClassName2(){

????????out.println(Person.class);

????}

????/**

????* get a instance of object, it will call the null param constructure

????* @throws Exception

????*/

????public void getNewInstance() throws Exception{

????????out.println(personClass.newInstance());

????}

????/**

????* get non-private constructor with params

????* @throws Exception

????*/

????public void getPublicConstructor() throws Exception{

????????//get constructor by params

????????Constructor constructor = personClass.getConstructor(String.class, int.class);

????????//use params constructor get a object instance

????????Person person = (Person)constructor.newInstance("lesslin", 27);

????????//print it out

????????out.println(person.getName());

????????out.println(person.getAge());

????}

????public void getPrivateConstructor() throws Exception{

????????//get the private constructor

????????Constructor con = personClass.getDeclaredConstructor(String.class);

????????//set the limits of authority

????????con.setAccessible(true);//delete the limits of authority

????????//new a instance by private constructor

????????Person person2 = (Person)con.newInstance("nainai");

????????//print it out

????????out.println("**" + person2.getName());

????????out.println("**" + person2.getAge());

????}

????/**

????* get public attribute

????* @throws Exception

????* @throws?

????*/

????public void getNotPrivateField() throws Exception{

????Constructor constructor = personClass.getConstructor(String.class, int.class);

????????Object obj = constructor.newInstance("aaa", 11);

????????Field field = personClass.getField("name");

????????field.set(obj, "bbb");

????????out.print(field.get(obj));

????}

????/**

????* get private attribute

????* @param args

????* @throws Exception

????* @throws?

????* @throws Exception

????*/

????public void getPrivateField() throws Exception{

????????Constructor constructor = personClass.getConstructor(String.class, int.class);

????????Object obj = constructor.newInstance("ccc", 33);

????????Field field2 = personClass.getDeclaredField("age");

????????field2.setAccessible(true);

????????field2.set(obj, 44);

????????out.println(field2.get(obj));

????}

????/**

????* get and call public method

????*/

????public void getNotPrivateMethod()throws Exception{

????????out.println(personClass.getMethod("toString"));

????????Object obj = personClass.newInstance();

????????Method method = personClass.getMethod("toString");

????????Object object = method.invoke(obj);

????????out.println(object);

????}

????/**

????* get and call private method

????* @param args

????* @throws Exception

????*/

????public void getPrivateMethod()throws Exception{

????????Object obj = personClass.newInstance();

????????Method method = personClass.getDeclaredMethod("getSth", String.class);

????????method.setAccessible(true);

????????Object value = method.invoke(obj, "test***********");

????????out.println(value);

????}

????/**

????* other method in reflect

????* @param args

????* @throws Exception

????*/

????public void otherMethod()throws Exception{

????????//get the class Loader

????????out.println(personClass.getClassLoader());

????????//get all the implement Interfaces

????????Class[] interfaces = personClass.getInterfaces();

????????for(Class class1 : interfaces){

????????????out.println(class1);

????????}

????????//reflect the direct super class of this class

????????out.println(personClass.getGenericSuperclass());

????????//is array

????????out.println(personClass.isArray());

????????out.println(new String[3].getClass().isArray());

????????//is Enum

????????out.println(personClass.isEnum());

????????//is interface

????????out.println(personClass.isInterface());

????}

????public static void main(String[] args) throws Exception {

????????MyReflect mr = new MyReflect();

????????mr.init();

????????// mr.getClassName();

????????// mr.getClassName2();

????????// mr.getNewInstance();

????????// mr.getPublicConstructor();

????????// mr.getPrivateConstructor();

????????// mr.getNotPrivateField();

????????// mr.getPrivateField();

????????mr.getNotPrivateMethod();

????????mr.getPrivateMethod();

????????mr.otherMethod();

????}

}


2. 動態(tài)代理

假設(shè)在原來的類中有一個public方法doSomething(),可以供5個客戶處理舊的業(yè)務(wù)邏輯∽幸現(xiàn)在有一個客戶希望修改doSomething()方法實現(xiàn)一個增強的業(yè)務(wù)邏輯扔仓,這時需求修改這個方法褐奥,但是這個方法還有剩余4個老客戶在調(diào)用。

所以我們不能只為了新業(yè)務(wù)需求修改doS omething()翘簇,導致其他模塊受影響撬码。那么我們可以通過動態(tài)代理的方式,擴展doSomething的方法實現(xiàn)版保,使得在原有的方法中增加更多的業(yè)務(wù)邏輯呜笑,但又不是修改soSomething。

動態(tài)代理:在不修改原業(yè)務(wù)的基礎(chǔ)上彻犁,基于原業(yè)務(wù)的方法叫胁,進行重新的擴展,實現(xiàn)新的業(yè)務(wù)汞幢。


Demo代碼:

IBoss是計價方法的interface接口,里面有一個抽象方法:

Boss類實現(xiàn)了IBoss接口的抽象方法:

SaleAction類是調(diào)用舊計價方法的類:

ProxyBoss是一個動態(tài)代理的工具類,實現(xiàn)了新計價方法的代理轉(zhuǎn)換:

ProxySaleAction類是使用動態(tài)代理來計價的類买乃,區(qū)別于舊的計價方式为牍,使用了動態(tài)代理:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蛀恩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌壳咕,老刑警劉巖谓厘,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件竟稳,死亡現(xiàn)場離奇詭異他爸,居然都是意外死亡,警方通過查閱死者的電腦和手機系谐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門纪他,熙熙樓的掌柜王于貴愁眉苦臉地迎上來止喷,“玉大人混聊,你說我怎么就攤上這事句喜】任福” “怎么了展懈?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵供璧,是天一觀的道長。 經(jīng)常有香客問我来惧,道長供搀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮棉钧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘摄悯。我一直安慰自己,他們只是感情好申钩,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布撒遣。 她就那樣靜靜地躺著义黎,像睡著了一般豁跑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上狐蜕,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天层释,我揣著相機與錄音快集,去河邊找鬼。 笑死个初,一個胖子當著我的面吹牛勃黍,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播马澈,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼痊班,長吁一口氣:“原來是場噩夢啊……” “哼摹量!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起凝果,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤器净,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后纠俭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冤荆,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡权纤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年涌庭,在試婚紗的時候發(fā)現(xiàn)自己被綠了欧宜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冗茸。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡夏漱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挂绰,到底是詐尸還是另有隱情服赎,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布践付,位于F島的核電站永高,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏曹傀。R本人自食惡果不足惜饲宛,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一落萎、第九天 我趴在偏房一處隱蔽的房頂上張望练链。 院中可真熱鬧,春花似錦媒鼓、人聲如沸绿鸣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽究流。三九已至芬探,卻和暖如春偷仿,著一層夾襖步出監(jiān)牢的瞬間宵蕉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工形入, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留亿遂,地道東北人。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓挪钓,卻偏偏與公主長得像碌上,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子馏予,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容