第89節:Java中的反射技術

来源:https://www.cnblogs.com/dashucoding/archive/2019/02/26/10435047.html
-Advertisement-
Play Games

第89節: 中的反射技術 反射技術是動態的獲取指定的類,和動態的調用類中的內容(沒有類前就可以創建對象,將對象的動作完成,這就是動態的獲取指定的類)。 配置文件把具體實現的類名稱定義到配置文件中。 反射技術的作用可以提高程式的擴展性。 類 用於創建並返回此對象的一個副本 用於指示其他某個對象是否與這 ...


第89節:Java中的反射技術

第89節:Java中的反射技術

反射技術是動態的獲取指定的類,和動態的調用類中的內容(沒有類前就可以創建對象,將對象的動作完成,這就是動態的獲取指定的類)。

配置文件把具體實現的類名稱定義到配置文件中。

反射技術的作用可以提高程式的擴展性。

Object

clone() 用於創建並返回此對象的一個副本

equals(Object obj) 用於指示其他某個對象是否與這個對象“相等”

getClass() 用於返回此Object的運行時類

hashCode() 用於返回該對象的哈希碼值

notify() 用於喚醒在此對象監視器上等待的單個線程

notifyAll() 用於喚醒在此對象監視器上等待的單個線程

notifyAll() 用於喚醒在此對象監視器上等待的所有線程

toString() 用於返回該對象的字元串

要獲取某文件中的成員,就要先獲取某文件的對象

public class Person{
 private String name;
 private int age;
 public Person(){
  super();
 }
 public Person(String name, int age){
  super();
  this.name = name;
  this.age = age;
 }
}

// 定義一個方法獲取對象
public static void getClass(){
 Person p = new Person();
 Class class = p.getClass();
}

public static void getClass(){
 String className = "com.dashucoding.Person";
 Class cla = Class.forName(className);
 
 Object obj = cla.newInstance();
 // 獲取創建位元組碼對象所表示的類的實例
 
}
pulic T newInstance() throws InstantiationException, IllegalAccessException
創建此Class對象所表示的類的一個實例,對一個帶有一個空參數列表的new表達式實例化這個類。

獲取構造函數

public static void getConstructorDemo() throws Exception {
 String className = "com.dashucodiing.Person";
 Class cla = Class.forName(className);

 Constructor cons = cla.getConstructor(String.class, int.class);
 Object obj = cons.newInstance("dashu",12);
}

獲取欄位

public static void getFieldDemo() throws Exception {
 String className = "com.dashucoding.Person";
 Class cla = Class.forName(className);
 
 String fieldName = "age";
 //獲取欄位
 Field field = cla.getField(fieldName);
 System.out.printlnn(field);
}
getField
public Field getField(String name) thows NoSuchFieldException, SecurityException.
返回一個Field對象。

NoSuchFieldException
如果沒有找到帶有指定名的欄位會報這個錯
NullPointerException
如果name為null會報這個錯

獲取方法

public static void getMethodDemo() throws Exception {
 String className = "com.dashucoding.Person";
 class cla = Class.forName(className);
 
 String methodName = "show";
  Method method = cla.getMethod( methodName, String.class,int.class);
 Object obj = cla.newInstance();
  method.invoke(obj, "dashu",12;
}

反射技術是這樣的以前先有類,才new對象,現在有了它之後,先new對象,把創建對象的動作做完,接著才在配置文件中添加哪個類。

當我們使用的類不明確時,通過配置文件告訴應用程式即可。

File configFile = new File("tempfile\\dashu.properties");
if(!configFile.exists()){
 configFile.createNewFile();
}

// 讀取配置文件
FileReader fr = new FileReader(configFile);
// 為了獲取其中的鍵值信息
Properties prop = new Properties();
prop.load(fr);
for(int x = 1; x<=prop.size(); x++){
 String className = prop.getProperty("dashu"+x);
 Class cla = Class.forName(className);
 class.newInstance();
}

類載入的概述:

如果某個類被這個程式使用時,如果這個類沒有被載入到記憶體中,就會由系統通過載入,連接,初始化三個步驟實現這個類並對其進行初始化。

載入是由記憶體進行class文件的讀取,簡單來說就是class文件讀入記憶體中,接著創建一個Class對象,任何類被使用的時候,由系統建立一個Class對象。(class文件載入到記憶體中)

連接:驗證,準備,解析

驗證內部結構是否正確
準備是否為類的靜態成員分配記憶體,並設置預設的初始化值
解析是將類的二進位數據中的符號引用換為直接引用哦

初始化進行初始化的操作

類載入器的概念

類載入器是把.class文件載入到記憶體中,並生成對應的Class對象。

類載入器的分類有哪些?

Bootstrap ClassLoader 根類載入器
Extension ClassLoader 擴展類載入器
System ClassLoader 系統類載入器

描述其作用:

Bootstrap ClassLoader 根類載入器

路徑 jre/lib/rt.jar文件 核心類的載入

Extension ClassLoader 擴展類載入器

路徑 jre/lib/ext目錄 jar包的載入

System ClassLoader 系統類載入器

jvm啟動時載入來自java命令的class文件

反射

源文件 -> 位元組碼 -> 創建對象
Class cla = Class.forName("類名"); // 讀取配置文件
Class cla = Person.class
Person p = new Person(); Class cla = p.getClass();

三種方式:

Class cla = Class.forName("com.dashucoding.Person");
Class cla1 = Person.class;
Person p = new Person();
Class cla2 = p.getClass();
System.out.println(cla = cla1);
System.out.println(cla2 = cla1);

Class.forName()讀取配置文件

public class Demo {
 public static void main(String[] args) throws Exception {
  Juicer j = new Juicer();
  j.run(new Apple());
 }

 class Apple {
  public void squeeze() {
   System.out.println();
  }
 } 
 class Juicer {
   public void run(Apple a) {
    a.squeeze();
   }
 }
}

interface Fruit {
 public void squeeze();
}
class Apple implements Fruit {
 public void squeeze(){
  System.out.println("");
 }
}

public static void main(String[] args) throws ClassNotFoundException {
 Class cla1 = Class.forName("com.dashucodiing.Person");
 Class cla2 = Person.class;
 Person p = new Person();
 Class cla3 = p.getClass();
}

通過反射獲取帶參構造方法

package com.dashucoding.demo
public class Demo {
 public static void main(String[] args) {
  Class clazz = Class.forName("com.dashucoding.bean.Person");
 // Person p = (Person) clazz.newInstance();
 Constructor c = clazz.getConstructor(String.class,int.class);
  Person p = (Person) c.newInstance("dashucoding",12);
 System.out.println(p);
 }
}

反射獲取成員變數

package com.dashucoding.demo
public class Demo {
 public static void main(String[] args) {
  Class clazz = Class.forName("com.dashucoding.bean.Person");

 Constructor c = clazz.getConstructor(String.class,int.class);
  Person p = (Person) c.newInstance("dashucoding",12);
  // 獲取
  Field f = clazz.getField("name");
  f.set(p, "李四");
  // Field f = clazz.getDeclaredField("name");
  // f.set(p, "李四");
 }
}

獲取方法

package com.dashucoding.demo
public class Demo {
 public static void main(String[] args) {
  Class clazz = Class.forName("com.dashucoding.bean.Person");

 Constructor c = clazz.getConstructor(String.class,int.class);
  Person p = (Person) c.newInstance("dashucoding",12);
  
 //獲取
 Method m = clazz.getMethod("say");
 m.invoke(p);
  
 Method m2 = clazz.getMethod("say",int.class);
 m.invoke(p,12);
 }
}

泛型

package com.dashucoding.demo
public class Demo {
 public static void main(String[] args) {
   ArrayList<Integer> list = new ArrayList<>();
   // list.add(1);
   Class clazz = Class.forName("java.util.ArrayList");
  Method m = clazz..getMethod("方法名", Object.class);
  m.invoke(list,"abc");
  System.out.println(list);
 }
}

propertyName改屬性值

public class Tool {
 public void setProperty (Object obj, String propertyName, Object value) throws Exception {
  Class clazz = obj.getClass();
  Field f = clazz.getDeclaredField(propertyName);
  f.setAccessible(true);
  f.set(obj, value);
 }
}
public static void main(String[] args){
 
 }

class Student {
 private String name;
 private int age;
 ...
}

反射

public class Demo {
 public void run() {
  System.out.println("dashucoding");
 }
}
// 配置文件 獲取這個名詞並載入這個類
com.dashucoding.test.Demo
public static void main(String[] args){
 BufferedReader br = new BufferedReader(new FileReader("xxx.properties"));
 Class clazz = Class.forName(br.readLine());
 
 Demo demo = (Demo) clazz.newInstance();
 demo.run();
}

動態代理

public interface User {
 public void add();
 public void delete();
}
public class UserImp implements User{
 @Override 
 public void add() {
  System.out.println("添加");
 }
 @Override
 public void delete(){
  System.out.println("刪除");
 }
}
public class Test {
 public static void main(String[] args){
  UserImp ui = new UserImp();
  ui.add();
  ui.delete();
 }
}

動態代理,在程式運行中產生對象。

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h);
new ProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h);

invoke(Object proxy, Method nethod, Object[] args);
public class MyInvocationHandler implements InvocationHandler {
 private Object target;
 public MyInvocationHandler (Object target) {
  this.target = target;
 }
 @Override
 public Object invoke(Object proxy,Method method,object[] args) throws Throwable {
 method.invoke(target,args);
  return null;
 }
}
MyInvocationHandler m = new MyInvocationHandler(si);
Student s = (Student)Proxy.newProxyInstance(ui.getClass().getClassLoader(), ui.getClass().getInterfaces(), m);

結言

好了,歡迎在留言區留言,與大家分享你的經驗和心得。

感謝你學習今天的內容,如果你覺得這篇文章對你有幫助的話,也歡迎把它分享給更多的朋友,感謝。

作者簡介

達叔,理工男,簡書作者&全棧工程師,感性理性兼備的寫作者,個人獨立開發者,我相信你也可以!閱讀他的文章,會上癮!,幫你成為更好的自己。長按下方二維碼可關註,歡迎分享,置頂尤佳。

感謝!承蒙關照!您真誠的贊賞是我前進的最大動力!

努力努力再努力Jeskson


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1.代碼生成器: [正反雙向](單表、主表、明細表、樹形表,快速開發利器)+快速表單構建器freemaker模版技術 ,0個代碼不用寫,生成完整的一個模塊,帶頁面、建表sql腳本、處理類、service等完整模塊2.多數據源:(支持同時連接無數個資料庫,可以不同的模塊連接不同數的據庫)支持N個數據源 ...
  • 一、什麼是OCTO 定義: OCTO是美團的分散式服務通信框架及服務治理系統,屬於公司級基礎設施,目前尚未開源。 目標: 為公司所有業務提供統一的服務通信框架,使業務具備良好的服務運營能力,輕鬆實現服務註冊、服務自動發現、負載均衡、容錯、灰度發佈、調用數據可視化等,持續提升服務高可用性、服務運維效率 ...
  • LieBrother原文 : "行為型模式:責任鏈模式" 十一大行為型模式之四:責任鏈模式。 簡介 姓名 :責任鏈模式 英文名 :Chain of Responsibility Pattern 價值觀 :責任歸我 個人介紹 : Avoid coupling the sender of a reque ...
  • 定義:裝飾模式是在不必改變原類文件和使用繼承的情況下,動態的擴展一個對象的功能。它是通過創建一個包裝對象,也就是裝飾來包裹真實的對象。 裝飾器模式是為已有功能添加更多功能的一種方式,就增加功能來說,裝飾器模式比通過生成子類更為靈活。該模式通過將裝飾的功能放在單獨的類中,並讓這些類包含了需要進行裝飾的 ...
  • 方法一:繼承 Thread 類,覆蓋方法 run(),我們在創建的 Thread 類的子類中重寫 run() ,加入線程所要執行的代碼即可。 下麵是一個例子: 這種方法簡單明瞭,符合大家的習慣,但是,它也有一個很大的缺點,那就是如果我們的類已經從一個類繼承(如小程式必須繼承自 Applet 類),則 ...
  • 一、格式化拼接、format 1.字元串拼接 name = "Monica", age = 16 print("姓名"+name+“年齡”+age+".") 2.占位符 %s:string,%d:整數,%f:浮點 info1 = ‘’‘姓名:%s 年齡:%s’‘’%(name,age) print( ...
  • 題意 "題目鏈接" Sol 題解好神仙啊qwq。 一般看到這種考慮最大值的貢獻的題目不難想到單調數據結構 對於本題而言,我們可以預處理出每個位置左邊第一個比他大的位置$l_i$以及右邊第一個比他大的位置$r_i$ 那麼$(l_i, r_i)$會產生$p1$的貢獻 $[l_i + 1, i 1]$和$ ...
  • 這一篇博客,是關於反反爬蟲的,我會分享一些我遇到的反爬蟲的措施,並且會分享我自己的解決辦法。如果能對你有什麼幫助的話,麻煩點一下推薦啦。 一、UserAgent UserAgent中文名為用戶代理,它使得伺服器能夠識別客戶使用的操作系統及版本、CPU 類型、瀏覽器及版本等信息。對於一些網站來說,它會 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...