日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

『设计模式』反射,反射程序员的快乐!为什么我老是加班?为什么我工资不如他多?原来是我不懂反射!

發布時間:2023/12/15 asp.net 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 『设计模式』反射,反射程序员的快乐!为什么我老是加班?为什么我工资不如他多?原来是我不懂反射! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

23種設計模式+額外常用設計模式匯總 (持續更新)
Java是一門準動態語言,是因為存在反射機制,如果你不會是不是就等于白學了?
看完不會,請評論,我親自給你解釋,嘻嘻!

什么是動態語言?

動態語言,是指程序在運行時可以改變其結構:新的函數可以被引進,已有的函數可以被刪除等在結構上的變化。比如JavaScript便是一個典型的動態語言。
  
除此之外如Ruby、Python、OC等也都屬于動態語言,而C、C++、Java等語言則不屬于動態語言。

動態類型語言,就是類型的檢查是在運行時做的,是不是合法的要到運行時才判斷,例如JavaScript就沒有編譯錯誤,只有運行錯誤。

靜態語言
  而靜態類型語言的類型判斷是在運行前判斷(如編譯階段),比如java就是靜態類型語言,靜態類型語言為了達到多態會采取一些類型鑒別手段,如繼承、接口,而動態類型語言卻不需要,

Java的反射機制被視為Java為準動態語言的主要的一個關鍵性質,這個機制允許程序在運行時透過反射取得任何一個已知名稱的class的內部信息,包括:

正在運行中的類的屬性信息,正在運行中的類的方法信息,正在運行中的類的構造信息,正在運行中的類的訪問修飾符,注解等等。

動態語言無時不刻在體現動態性,而靜態語言也在通過其他方法來趨近于去彌補靜態語言的缺陷。

為什么么要使用反射:

  • 反射是框架設計的靈魂
    框架: 半成品軟件。可以在框架的基礎上進行軟件開發,簡化編碼。學習框架并不需要了解反射,但是要是想自己寫一個框架,那么就要對反射機制有很深入的了解。
  • 解耦,提高程序的可擴展性
  • 在運行時判斷任意一個對象所屬的類。
  • 在運行時構造任意一個類的對象。
  • 在運行時判斷任意一個類所具有的成員變量和方法。
  • 在運行時調用任意一個對象的方法。
  • 什么是反射:

    定義:

    JAVA反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為java語言的反射機制。

    簡單來說: 將類的各個組成部分封裝成其他對象

    反射機制的實現原理

    Java代碼在計算機中經歷的三個階段

  • Source源代碼階段:.java被編譯成.class字節碼文件。
  • Class類對象階段:*.class字節碼文件被類加載器加載進內存,并將其封裝成Class對象(用于在內存中描述字節碼文件),Class對象將原字節碼文件中的成員變量抽取出來封裝成數組Field[],將原字節碼文件中的構造函數抽取出來封裝成數組Construction[],在將成員方法封裝成Method[]。當然Class類內不止這三個,還封裝了很多,我們常用的就這三個。
  • RunTime運行時階段:創建對象的過程new。
  • 獲取Class對象的方式:
  • Class.forname(“類全名”):
    將字節碼加載進內存,返回Class對象。
    一般用于: 配置文件,將類名定義在配置文件中,讀取文件,加載類。
  • 類名.class:
    通過類名的屬性Class獲取
    一般用于: 參數傳遞
  • 對象.getclass()獲取:
    getclass()方法在Object類中定義
    一般用于: 對象獲取字節碼的方式
  • 補充:
    同一個字節碼文件(*.class)在一次程序運行中,只會被加載一次,不論通過哪一種方式獲取的Class對象都是同一個。

    舉例:

    public void Main() throws ClassNotFoundException {//方式一:Class.forName("全類名");Class cls1 = Class.forName("Test.Test"); //Person自定義實體類System.out.println("cls1 = " + cls1);//方式二:類名.classClass cls2 = Test.class;System.out.println("cls2 = " + cls2);//方式三:對象.getClass();Test tst= new Test(); Class cls3 =tst.getClass();System.out.println("cls3 = " + cls3);// == 比較三個對象System.out.println("cls1 == cls2 : " + (cls1 == cls2)); //trueSystem.out.println("cls1 == cls3 : " + (cls1 == cls3)); //true//結論:同一個字節碼文件(*.class)在一次程序運行過程中,只會被加載一次,無論通過哪一種方式獲取的Class對象都是同一個。 }

    Class對象功能:
    獲取功能:

    1 獲取成員變量們

    Field[] getFields() :獲取所有public修飾的成員變量 Field getField(String name) 獲取指定名稱的 public修飾的成員變量Field[] getDeclaredFields() 獲取所有的成員變量,不考慮修飾符 Field getDeclaredField(String name) //需要忽略訪問權限修飾符的安全檢查 setAccessible(true):暴力反射,不然會報錯

    具體測試看下文!

    2.獲取構造方法們

    Constructor<?>[] getConstructors() Constructor<T> getConstructor(<?>... parameterTypes) Constructor<?>[] getDeclaredConstructors() Constructor<T> getDeclaredConstructor(<?>... parameterTypes)

    具體測試看下文!

    3.獲取成員方法們:

    Method[] getMethods() Method getMethod(String name,<?>... parameterTypes) Method[] getDeclaredMethods() Method getDeclaredMethod(String name,<?>... parameterTypes) //需要忽略訪問權限修飾符的安全檢查 setAccessible(true):暴力反射,不然會報錯

    具體測試看下文!

    4.獲取全類名

    String getName()

    getClass()方法是Object類的方法,需要注意一點獲取的類名是全類名(帶有路徑)
    舉例:

    package Test; public class Reflect {public static void main(String[] args) throws Exception {Class Tst = Test.class;String s=Tst.getName(); System.out.println(s);} }

    運行結果:

    ![在這里插入圖片描述](https://img-blog.csdnimg.cn/20200503024319516.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzYyNzExOA==,size_16,color_FFFFFF,t_70)
    Field:成員變量
  • 設置值 void set(Object obj, Object value)
  • 獲取值 get(Object obj)
  • 舉例:

    package Test; public class Test {public String a;protected String b;private String c;String d; }package Test;import java.lang.reflect.Field;public class Reflect {public static void main(String[] args) throws Exception {Class Tst = Test.class;Test tst=new Test();System.out.println("-------------------測試getField--------------------");Field[] fields=Tst.getFields(); for(Field f:fields){System.out.println(f);}Field a=Tst.getField("a");a.set(tst, "我是設置值");System.out.println(a.get(tst));System.out.println("\n-------------測試getDeclaredField------------------");Field[] fields2=Tst.getDeclaredFields();for(Field f:fields2){f.setAccessible(true);//不加出不來,詳情請看上文System.out.println(f);}Field b=Tst.getDeclaredField("b");b.set(tst, "我是私有的設置值");System.out.println(b.get(tst));} }

    測試結果:

    Constructor:構造方法

    創建對象:T newInstance(Object… initargs)
    注意:如果使用空參數構造方法創建對象,操作可以簡化:Class對象的newInstance方法
    作用就是用它來創建對象
    舉例:

    package Test;public class Test {public String a;//構造方法public Test( ) {}public Test(String a) {this.a = a;}}package Test;import java.lang.reflect.Constructor; import java.lang.reflect.Field;public class Reflect {public static void main(String[] args) throws Exception {Class Tst = Test.class;Constructor[] constructors = Tst.getConstructors();for (Constructor constructor : constructors) { // Constructor 對象reflect包下的 import java.lang.reflect.Constructor;System.out.println(constructor);}System.out.println("------------------無參構造函數創建對象----------------------");Constructor cst=Tst.getConstructor(); //獲得無參構造函數System.out.println(cst);Object test=cst.newInstance(); //利用無參構造函數創建對象System.out.println(test);System.out.println("------------------有參構造函數創建對象----------------------");Constructor cst2=Tst.getConstructor(String.class); //獲得有參構造函數System.out.println(cst2);Object test2=cst2.newInstance("張3");//利用有參構造函數創建對象System.out.println(test2);System.out.println("------------------基于Class創建對象----------------------");Object test3=Tst.newInstance();//只能用于無參構函數,而且已經被棄用,不建議使用System.out.println(test3);} }


    喜歡問問題的小朋友要來了?
    為什么沒有getDeclaredConstructor方法和getDeclaredConstructors方法?
    為什么?為什么?
    有啊!!
    getDeclaredConstructor方法可以獲取到任何訪問權限的構造器,而getConstructor方法只能獲取public修飾的構造器。具體不再測試。此外在構造器的對象內也有setAccessible(true);方法,并設置成true就可以操作了。
    關于為什么要使用private訪問權限的構造器,使用這個構造器不就不能外部訪問了嘛,不也就無法進行實例化對象了嗎?無法在類的外部實例化對象正是私有構造器的意義所在,在單例模式下經常使用,整個項目只有一個對象,外部無法實例化對象,可以在類內的進行實例化并通過靜態方法返回,由于實例化的對象是靜態的,故只有一個對象,也就是單例的,這就是單例模式中的餓漢模式,不管是否調用,都創建一個對象。

    Method:方法對象

    執行方法:Object invoke(Object obj, Object… args)
    獲取方法名稱:String getName();

    舉例:

    package Test;public class Test {public String a;// 構造方法public Test() {}public Test(String a) {this.a = a;}public void do_Something() {System.out.println("吃飯睡覺打豆豆");}public String do_Something(String s) {System.out.println("吃飯睡覺打"+s);return "爽";} }package Test;import java.lang.reflect.Method;public class Reflect {public static void main(String[] args) throws Exception {Class Tst = Test.class;Method[] mtd=Tst.getMethods();for(Method m:mtd) System.out.println(m);} }

    運行結果:

    舉例2.0:

    package Test;public class Test {public String a;// 構造方法public Test() {}public Test(String a) {this.a = a;}public void do_Something() {System.out.println("吃飯睡覺打豆豆");}public String do_Something(String s) {System.out.println("吃飯睡覺打"+s);return "爽";} } package Test;import java.lang.reflect.Method;public class Reflect {public static void main(String[] args) throws Exception {Class Tst = Test.class;Test test = new Test();System.out.println("-----------------無參測試----------------------");Method mtd1 = Tst.getMethod("do_Something");// 獲得無參的方法Object return_Value = mtd1.invoke(test); // 調用方法// 有返回值就得到一個值,沒有就得到一個nullSystem.out.println(return_Value);System.out.println("-----------------含參測試----------------------");Method mtd2 = Tst.getMethod("do_Something", String.class);// 獲得無參的方法Object return_Value2 = mtd2.invoke(test, "張三"); // 調用方法// 有返回值就得到一個值,沒有就得到一個nullSystem.out.println(return_Value2);} }

    運行結果:

    總結

    這時候又會有小朋友問:
    為什么要這么麻煩,我直接調用不就好了?

    不知你是否發現,從類的創建的方法的使用,所有的一切都是用的字符串,那么也就是說,我可以通過讀入數據,或者配置文件的方式,創建類,調用方法。

    舉個簡單點的例子:
    就拿英雄聯盟這款游戲來說,這游戲三天兩頭的輪換一個娛樂模式,難道每次上線都要對源代碼進行修改,今天在Client調用“無限活力”,明天就要調用"魄羅大亂斗”,每天就對著源碼改?幾萬行的代碼就這么放心讓你改?除非你老板想做空公司,故意的!必然不可能,這時候我們就算哪一個txt文件,就放一行字符串,用反射之后,只用改txt文件不就完了!不用反射,是做不到用字符串創建類,和運行方法(別抬杠,寫個if-else 或者 switch啥的)。

    舉例可能不太恰當,一般不會使用txt,一般使用XML或者java配置文件。

    寫在最后:
    我叫風骨散人,名字的意思是我多想可以不低頭的自由生活,可現實卻不是這樣。家境貧寒,總得向這個世界低頭,所以我一直在奮斗,想改變我的命運給親人好的生活,希望同樣被生活綁架的你可以通過自己的努力改變現狀,深知成年人的世界里沒有容易二字。目前是一名在校大學生,預計考研,熱愛編程,熱愛技術,喜歡分享,知識無界,希望我的分享可以幫到你!
    如果有什么想看的,可以私信我,如果在能力范圍內,我會發布相應的博文!
    感謝大家的閱讀!😘你的點贊、收藏、關注是對我最大的鼓勵!

    總結

    以上是生活随笔為你收集整理的『设计模式』反射,反射程序员的快乐!为什么我老是加班?为什么我工资不如他多?原来是我不懂反射!的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 在线视频观看国产 | 亚洲精品一区二区三区精华液 | 嫩草视频国产 | 国产成a人亚洲精v品无码 | 国产裸体舞一区二区三区 | 蜜桃久久精品成人无码av | 欧美日韩精品一区二区在线观看 | 国产欧美综合一区二区三区 | 男女搞黄网站 | 黑人操亚洲人 | 亚洲玖玖爱| 91成人在线观看喷潮蘑菇 | 婷婷激情五月综合 | 午夜大片| 伊人欧美在线 | 老司机午夜免费福利 | 国语对白永久免费 | 美女免费网站 | 欧美黄色大片免费观看 | 国产又粗又猛又爽视频 | 国产精品入口麻豆九色 | 成人短视频在线 | 3d动漫精品啪啪一区二区免费 | 人妻与黑人一区二区三区 | 玖玖国产精品视频 | 最新av网站在线观看 | h官场少妇第三部分 | www.日韩av.com | 亚洲AV无码国产精品 | 爱插网 | 天天色综合1| 美女啪啪动态图 | 亚洲伊人久久久 | 欧美国产第一页 | 欧美激情校园春色 | 美女免费毛片 | 欧美日韩天堂 | 久久小视频 | 97超碰导航 | 国产污污在线观看 | 国产精欧美一区二区三区白种人 | 阿v天堂在线观看 | 朝桐光在线观看 | 毛片h| 日韩成人短视频 | 翔田千里x88aⅴ | av九九九| 亚洲丝袜色图 | 久久爱综合网 | 伦一理一级一a一片 | 国产欧美日本 | 先锋影音av资源站 | 求av网站 | 污黄视频网站 | 99热只有这里有精品 | 91网址入口 | 成人在线网站 | 天堂视频免费 | 亚洲另类图区 | 国产精品久久不卡 | 国产又大又黑又粗免费视频 | 日本少妇做爰全过程毛片 | 国产视频综合在线 | 久久精品久久久精品美女 | 中文字幕人妻一区二区 | 亚洲av永久无码精品 | 特级黄色大片 | av不卡免费在线观看 | 欧美日韩欧美 | 亚洲激情四射 | 亚洲大乳| 精品亚洲精品 | 97高清国语自产拍 | 国产传媒av在线 | 91日韩中文字幕 | 黄页网站免费在线观看 | 麻豆影视国产在线观看 | 久久久久久中文字幕 | 亚洲乱码国产乱码精品精大量 | 97视频免费在线 | 又大又硬又爽免费视频 | 国产精品国语自产拍在线观看 | 自拍第二页 | 国产亚洲欧美视频 | av大帝在线观看 | 亚洲激情一区二区 | 日日摸夜夜爽 | 国内精品久久久 | 色黄啪啪网 | 大香依人 | 亚洲精品国产精品国自产观看浪潮 | 在线观看一区二区三区四区 | 中文字幕免费在线观看视频 | 男受被做哭激烈娇喘gv视频 | 夜夜草| 欧洲亚洲一区 | 狠狠人妻久久久久久综合 | 很色的网站 | 天天想你在线观看完整版电影高清 |