java 反射機制及動態(tài)代理

反射概述
Reflection(反射)是Java被視為動態(tài)語言的關(guān)鍵揖庄,反射機制允許程序在執(zhí)行期借助于Reflection API取得任何類的內(nèi)部信息子檀,并能直接操作任意對象的內(nèi)部屬性及方法正塌。

Java反射機制主要提供了以下功能:

在運行時構(gòu)造任意一個類的對象
在運行時獲取任意一個類所具有的成員變量和方法
在運行時調(diào)用任意一個對象的方法(屬性)
生成動態(tài)代理

Class 是一個類; 一個描述類的類.
   封裝了描述方法的 Method,
描述字段的 Filed,
描述構(gòu)造器的 Constructor 等屬性.
下面我們以student為例 一一介紹

先說獲取Class對象的三種方式
1.通過類名獲取 類名.class
2.通過對象獲取 對象名.getClass()
3.通過全類名獲取 Class.forName(全類名)

   //類名.class
    Class<ConStudent> conSC = ConStudent.class;
    System.out.print("---------類名.class---------"+"\n");
    //對象名.getClass()
    ConStudent conStudent = new ConStudent();
    Class<? extends ConStudent> conSC1 = conStudent.getClass();
    System.out.print("---------對象名.getClass()---------"+"\n");
    //Class.forName(全類名)
    Class<?> conSC2 = Class.forName("com.reflection.ConStudent");
    System.out.print("---------Class.forName(全類名)---------");

---------類名.class---------
靜態(tài)代碼:10
---------對象名.getClass()---------
靜態(tài)代碼:10
---------Class.forName(全類名)---------

public class ConStudent {

public static int number = 10;
static {
    System.out.print("靜態(tài)代碼:"+number+"\n");
}

}

通過以上方式可以看出 第二第三種方式是直接調(diào)用靜態(tài)代碼的 從方便和效率來看 第三中方式是最好的 第一種也不錯 第二種是不推薦的 個人建議 僅供參考

現(xiàn)在說一下 Constructor

先看一下 實體類

/**

  • Constructor
    */
    public class ConStudent {

    public ConStudent(){
    System.out.print("ConStudent空參構(gòu)造函數(shù)"+"\n");
    }

    public ConStudent(double score) {
    System.out.print("ConStudent有參構(gòu)造函數(shù)"+"\n");
    }

    private ConStudent(int age) {
    System.out.print("ConStudent私有構(gòu)造帶參數(shù)"+age+"\n");
    }
    protected ConStudent(String name){
    System.out.print("ConStudent受保護的構(gòu)造參數(shù)"+name+"\n");
    }

}
private static void constructor() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

    Class<?> conSC = Class.forName("com.reflection.ConStudent");
    Constructor<?>[] constructors = conSC.getConstructors();
    for (Constructor c :constructors){
        System.out.print("ReflectTest所有公有構(gòu)造:"+c+"\n");
    }
    System.out.print("ReflectTest----------分割線-------------"+"\n");

    Constructor<?>[] declaredConstructors = conSC.getDeclaredConstructors();
    for (Constructor c : declaredConstructors){

        System.out.print("ReflectTest所有構(gòu)造方法:"+c+"\n");
    }
    System.out.print("ReflectTest----------分割線-------------"+"\n");
    Constructor constructor = conSC.getConstructor();
    System.out.print("ReflectTest公有無參構(gòu)造方法"+constructor+"\n");
    System.out.print("ReflectTest----------分割線-------------"+"\n");
    Constructor<?> declaredConstructor = conSC.getDeclaredConstructor(int.class);
    System.out.print("ReflectTest私有構(gòu)造方法"+declaredConstructor+"\n");
    declaredConstructor.setAccessible(true);
    Object o = declaredConstructor.newInstance(11);
    System.out.print("ReflectTest調(diào)用私有構(gòu)造"+o+"\n");
    System.out.print("ReflectTest----------分割線-------------"+"\n");
    Constructor<?> declaredConstructor1 = conSC.getDeclaredConstructor(String.class);
    declaredConstructor1.setAccessible(true);
    Object maoge = declaredConstructor1.newInstance("maoge");
    System.out.print("ReflectTest受保護的構(gòu)造:"+maoge);

}

輸出內(nèi)容

ReflectTest所有公有構(gòu)造:public com.reflection.ConStudent(double)
ReflectTest所有公有構(gòu)造:public com.reflection.ConStudent()
ReflectTest----------分割線-------------
ReflectTest所有構(gòu)造方法:protected com.reflection.ConStudent(java.lang.String)
ReflectTest所有構(gòu)造方法:private com.reflection.ConStudent(int)
ReflectTest所有構(gòu)造方法:public com.reflection.ConStudent(double)
ReflectTest所有構(gòu)造方法:public com.reflection.ConStudent()
ReflectTest----------分割線-------------
ReflectTest公有無參構(gòu)造方法public com.reflection.ConStudent()
ReflectTest----------分割線-------------
ReflectTest私有構(gòu)造方法private com.reflection.ConStudent(int)
ConStudent私有構(gòu)造帶參數(shù)11
ReflectTest調(diào)用私有構(gòu)造com.reflection.ConStudent@14ae5a5
ReflectTest----------分割線-------------
ConStudent受保護的構(gòu)造參數(shù)maoge
ReflectTest受保護的構(gòu)造:com.reflection.ConStudent@7f31245a
Process finished with exit code 0

下面看一下 Filed
實體也是三個參數(shù) 代表三種權(quán)限

/**

  • Filed
    */
    public class FiledStudent {
    public int age;
    private String name;
    protected double score;

    @Override
    public String toString() {
    return "FiledStudent{" +
    "age=" + age +
    ", name='" + name + ''' +
    ", score=" + score +
    '}';
    }

    public int getAge() {
    return age;
    }

    public void setAge(int age) {
    this.age = age;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    public double getScore() {
    return score;
    }

    public void setScore(double score) {
    this.score = score;
    }
    }

private static void filedTest() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> filedSC = Class.forName("com.reflection.FiledStudent");
Field[] fields = filedSC.getFields();
for (Field f :fields){
System.out.print("ReflectTest所有公有的參數(shù):"+f+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Field age = filedSC.getField("age");
Object o = filedSC.getConstructor().newInstance();
age.set(o,11);
FiledStudent student = (FiledStudent) o;
System.out.print("ReflectTest獲取公有參數(shù):"+student.getAge()+"\n");
System.out.print("ReflectTest----------分割線-------------"+"\n");
Field[] declaredFields = filedSC.getDeclaredFields();
for (Field f :declaredFields){
System.out.print("ReflectTest獲取所有參數(shù):"+f+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Field name = filedSC.getDeclaredField("name");
name.setAccessible(true);
name.set(o,"Maoge");

    System.out.print("ReflectTest獲取指定的私有參數(shù):"+student.getName()+"\n");
    System.out.print("ReflectTest----------分割線-------------"+"\n");
    Field score = filedSC.getDeclaredField("score");
    score.setAccessible(true);
    score.set(o,9.8);
    System.out.print("ReflectTest獲取受保護的參數(shù):"+student.getScore());

}

下面看 mothed

/**

  • Method
    */
    public class MethodStudent{
    int age;
    String name;
    double score;

    public void showName( ){
    System.out.print("(公共)姓名:");
    }
    private void showAge(){
    System.out.print("(私有)年齡:");
    }
    protected void showScore(){
    System.out.print("(保護)分數(shù):");
    }

    public String printName(String name){
    System.out.print("(公共string)name:"+name);
    return name;
    }
    private double printScore(double score){
    System.out.print("(私有double)score:"+score);
    return score;
    }
    protected int printAge(int age){
    System.out.print("(保護age)age:"+age);
    return age;
    }

}

private static void methodTest() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> methodSC = Class.forName("com.reflection.MethodStudent");
Method[] declaredMethods = methodSC.getDeclaredMethods();
for (Method m : declaredMethods){
System.out.print("ReflectTest 獲取所有的方法:"+m+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Method[] methods = methodSC.getMethods();
for (Method m : methods){
System.out.print("ReflectTest獲取所有的公有方法"+m+"\n");
}
System.out.print("ReflectTest----------分割線-------------"+"\n");
Method score = methodSC.getDeclaredMethod("printScore", double.class);
Object o = methodSC.getConstructor().newInstance();
score.setAccessible(true);
Object invoke = score.invoke(o, 9.8);
System.out.print("ReflectTest調(diào)用制定的私有方法:"+invoke+"\n");
System.out.print("ReflectTest----------分割線-------------"+"\n");

    Method printName = methodSC.getMethod("printName", String.class);
    Object maoge = printName.invoke(o, "Maoge");
    System.out.print("ReflectTest公有有參數(shù)方法:"+maoge+"\n");
    System.out.print("ReflectTest----------分割線-------------"+"\n");
    Method showName = methodSC.getMethod("showName", null);
    System.out.print("ReflectTest公有無參方法:"+showName+"\n");
    System.out.print("ReflectTest----------分割線-------------"+"\n");
    Method printAge = methodSC.getDeclaredMethod("printAge", int.class);
    printAge.setAccessible(true);
    Object invoke1 = printAge.invoke(o, 20);
    System.out.print("ReflectTest受保護的方法:"+invoke1);
}

這是反射的一些基礎(chǔ)使用

下面說一下動態(tài)代理 (代理可以讓我們的方法或者類進行功能擴展 解耦等好處)

新建一個接口

public interface Person {
void work();
}

新建一個接口實現(xiàn)類(被角色代理)

public class PersonImpl implements Person{

@Override
public void work() {
    System.out.print("i am PersonImpl.calss");

}

}

新建一個代理角色

public class PersonHandler implements InvocationHandler {
public Object px;

public PersonHandler(Object px) {
    this.px = px;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.print("do work"+"\n");
    return method.invoke(px,args);
}

}

綁定代理

public class PersonProxyTest {
public static void main(String[] args) {
Person person = new PersonImpl();
Person o = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, new PersonHandler(person));
o.work();
}

}

好了 本文到此結(jié)束 歡迎留言或私信

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末致燥,一起剝皮案震驚了整個濱河市配喳,隨后出現(xiàn)的幾起案子蹂安,更是在濱河造成了極大的恐慌,老刑警劉巖彰阴,帶你破解...
    沈念sama閱讀 212,599評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘾敢,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機簇抵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,629評論 3 385
  • 文/潘曉璐 我一進店門庆杜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人碟摆,你說我怎么就攤上這事晃财。” “怎么了典蜕?”我有些...
    開封第一講書人閱讀 158,084評論 0 348
  • 文/不壞的土叔 我叫張陵拓劝,是天一觀的道長。 經(jīng)常有香客問我嘉裤,道長郑临,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,708評論 1 284
  • 正文 為了忘掉前任屑宠,我火速辦了婚禮厢洞,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘典奉。我一直安慰自己躺翻,他們只是感情好,可當我...
    茶點故事閱讀 65,813評論 6 386
  • 文/花漫 我一把揭開白布卫玖。 她就那樣靜靜地躺著公你,像睡著了一般。 火紅的嫁衣襯著肌膚如雪假瞬。 梳的紋絲不亂的頭發(fā)上陕靠,一...
    開封第一講書人閱讀 50,021評論 1 291
  • 那天,我揣著相機與錄音脱茉,去河邊找鬼剪芥。 笑死,一個胖子當著我的面吹牛琴许,可吹牛的內(nèi)容都是我干的税肪。 我是一名探鬼主播,決...
    沈念sama閱讀 39,120評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼榜田,長吁一口氣:“原來是場噩夢啊……” “哼益兄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起箭券,我...
    開封第一講書人閱讀 37,866評論 0 268
  • 序言:老撾萬榮一對情侶失蹤净捅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后邦鲫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體灸叼,經(jīng)...
    沈念sama閱讀 44,308評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,633評論 2 327
  • 正文 我和宋清朗相戀三年庆捺,在試婚紗的時候發(fā)現(xiàn)自己被綠了古今。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,768評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡滔以,死狀恐怖捉腥,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情你画,我是刑警寧澤抵碟,帶...
    沈念sama閱讀 34,461評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站坏匪,受9級特大地震影響拟逮,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜适滓,卻給世界環(huán)境...
    茶點故事閱讀 40,094評論 3 317
  • 文/蒙蒙 一敦迄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧凭迹,春花似錦罚屋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,850評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至鱼鸠,卻和暖如春猛拴,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蚀狰。 一陣腳步聲響...
    開封第一講書人閱讀 32,082評論 1 267
  • 我被黑心中介騙來泰國打工漆弄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人造锅。 一個月前我還...
    沈念sama閱讀 46,571評論 2 362
  • 正文 我出身青樓撼唾,卻偏偏與公主長得像,于是被迫代替她去往敵國和親哥蔚。 傳聞我的和親對象是個殘疾皇子倒谷,可洞房花燭夜當晚...
    茶點故事閱讀 43,666評論 2 350

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