欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一篇文章帶你搞定JAVA反射

 更新時(shí)間:2021年07月14日 17:09:43   作者:香菜聊游戲  
這篇文章主要介紹了Java反射機(jī)制的簡(jiǎn)單講解,本文講解了Java的高級(jí)概念反射機(jī)制,通過文字介紹案例該項(xiàng)概念和代碼的詳細(xì)展示,需要的朋友可以參考下

1、反射的概念

1、概念

反射,指在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法,對(duì)任意一個(gè)對(duì)象,都能調(diào)用它的任意一個(gè)方法。這種動(dòng)態(tài)獲取信息,以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能,叫做java語言的反射機(jī)制。反射很強(qiáng)大,有優(yōu)點(diǎn)也有缺點(diǎn)。

優(yōu)點(diǎn):靈活性高。因?yàn)榉瓷鋵儆趧?dòng)態(tài)編譯,即只有到運(yùn)行時(shí)才動(dòng)態(tài)創(chuàng)建 &獲取對(duì)象實(shí)例。

缺點(diǎn):執(zhí)行效率低。

2、獲取字節(jié)碼文件對(duì)象的方式

2.1 元數(shù)據(jù)的概念

元數(shù)據(jù)(metadata):元數(shù)據(jù)是指用來描述類的數(shù)據(jù),就是class的代碼數(shù)據(jù)。所有的class文件加載到虛擬機(jī)之后都會(huì)被構(gòu)建成class對(duì)象,class對(duì)象描述了一個(gè)類都有哪些東西,大家都知道的實(shí)現(xiàn)的接口,繼承的抽象類,成員變量,類變量,成員方法,類方法,靜態(tài)方法等,這個(gè)class對(duì)象就是元數(shù)據(jù)。

  • Class類:代表一個(gè)類。
  • Field類:代表類的成員變量(成員變量也稱為類的屬性)。
  • Method類:代表類的方法。
  • Constructor類:代表類的構(gòu)造方法。

圖片

2.2 獲取class對(duì)象的方式

  • 通過對(duì)象獲得,因?yàn)槿魏螌?duì)象都必須和class對(duì)象關(guān)聯(lián)
  • 通過類對(duì)象直接獲得
  • 通過類加載器獲得,因?yàn)轭惣虞d器讀取class文件會(huì)返回class對(duì)象

即將用來反射的對(duì)象(隨便定義的一個(gè)對(duì)象,只是為了演示)

package org.pdool.reflect;
 
/**
* @author 香菜
*/
public class Npc {
  // 靜態(tài)field
  public static int NPC_TYPE_1 = 1;
  // 私有成員變量
  private int npcType;
  // 共有成員變量
  public String name;
  // 無參構(gòu)造函數(shù)
  public Npc() {
  }
  // 有參構(gòu)造函數(shù)
  public Npc(int npcType, String name) {
      this.npcType = npcType;
      this.name = name;
  }
 
  public int getNpcType() {
      return npcType;
  }
 
  public void setNpcType(int npcType) {
      this.npcType = npcType;
  }
 
  public String getName() {
      return name;
  }
 
  public void setName(String name) {
      this.name = name;
  }
  // 靜態(tài)方法
  public static void sayHello(String word){
      System.out.println("hello " + word);
  }
}

獲取反射class的三種方式

package org.pdool.reflect;
 
/**
* @author 香菜
*/
public class ClazzTest {
   public static void main(String[] args) {
       //第一種方式獲取Class對(duì)象
       Npc npc1 = new Npc();//這一new 產(chǎn)生一個(gè)Npc對(duì)象,一個(gè)Class對(duì)象。
       Class npcClazz1 = npc1.getClass();//獲取Class對(duì)象
       System.out.println(npcClazz1.getName());
 
       //第二種方式獲取Class對(duì)象
       Class npcClazz2 = Npc.class;
       System.out.println(npcClazz1 == npcClazz2);//判斷第一種方式獲取的Class對(duì)象和第二種方式獲取的是否是同一個(gè)
 
       //第三種方式獲取Class對(duì)象
       try {
           Class npcClazz3 = Class.forName("org.pdool.reflect.Npc");//注意此字符串必須是真實(shí)路徑,就是帶包名的類路徑,包名.類名
           System.out.println(npcClazz3 == npcClazz2);//判斷三種方式是否獲取的是同一個(gè)Class對(duì)象
      } catch (ClassNotFoundException e) {
           e.printStackTrace();
      }
 
  }
}

1、訪問權(quán)限

反射機(jī)制的默認(rèn)行為受限于Java的訪問控制,可通過 setAccessible 繞過控制。

// 設(shè)置對(duì)象數(shù)組可訪問標(biāo)志
static void setAccessible(AccessibleObject[] array, boolean flag)  

2、獲取方法

圖片

2.1 訪問靜態(tài)方法

public static void main(String[] args) throws NoSuchMethodException,InvocationTargetException, IllegalAccessException {
       Npc npc = new Npc(1, "妖神·凰女");
       Class npcClazz = Npc.class;
       // 第一個(gè)參數(shù)是方法名,第二個(gè)參數(shù)是函數(shù)的參數(shù)class對(duì)象,因?yàn)榇嬖谥剌d的可能性,用參數(shù)類型區(qū)分
       Method sayHello = npcClazz.getMethod("sayHello", String.class);
       sayHello.invoke(npc, "world");
  }

2.2 訪問類方法

      Npc npc = new Npc(1, "妖神·凰女");
      System.out.println(npc.getName());
      Class npcClazz = Npc.class;
      // 第一個(gè)參數(shù)是方法名,第二個(gè)參數(shù)是函數(shù)的參數(shù)class對(duì)象,因?yàn)榇嬖谥剌d的可能性,用參數(shù)類型區(qū)分
      Method sayHello = npcClazz.getMethod("setName", String.class);
      sayHello.invoke(npc, "world");
      System.out.println(npc.getName());

 3、獲取字段,讀取字段的值

圖片

       Npc npc = new Npc(1, "妖神·凰女");
       Class npcClazz = Npc.class;
       // 獲取字段,并設(shè)置可訪問
       Field field = npcClazz.getField("name");
       field.setAccessible(true);
       System.out.println( field.get(npc));

4、獲取實(shí)現(xiàn)的接口

圖片

5、獲取構(gòu)造函數(shù),創(chuàng)建實(shí)例

圖片

    Class npcClazz = Npc.class;
               Constructor declaredConstructor = npcClazz.getDeclaredConstructor(int.class,String.class);
       Npc npc = (Npc) declaredConstructor.newInstance(1, "妖神");
       System.out.println(npc.getName());

6、獲取繼承的父類

Class npcClazz = Npc.class;
Class superclass = npcClazz.getSuperclass();
System.out.println(superclass.getName());

7、獲取注解

Class npcClazz = Npc.class;
       Annotation[] annotations = npcClazz.getAnnotations();
// 運(yùn)行時(shí)注解
       for (Annotation annotation : annotations) {
           System.out.println(annotation.getClass().getName());
      }

4、反射實(shí)例

獲取到元數(shù)據(jù)不是最終的目的,我們最終的目的是想在運(yùn)行時(shí)去調(diào)用,訪問類。說了太多,還是舉個(gè)例子,大家都知道Spring的IOC,怎么實(shí)現(xiàn)的吶?

過程:

1、Spring 在項(xiàng)目啟動(dòng)的時(shí)間通過讀取xml中配置的bean的路徑,

2、然后通過Class.forName 讀取class 到類加載器,

3、然后通過反射創(chuàng)建所有的bean實(shí)例并保存到容器中,啟動(dòng)容器之后,

4、在項(xiàng)目中可以直接獲取bean對(duì)象。

我們來大概實(shí)現(xiàn)這一過程,因?yàn)閤ml的讀取比較麻煩,直接用property來代替了。大家體會(huì)一下思想就可以了。

package org.pdool.reflect;
 
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
 
/**
* @author 香菜
*/
public class ClazzTest {
  public static void main(String[] args){
      try {
          Map<String,Object> container = new HashMap<>();
          //1.讀取配置
          InputStream in = ClazzTest.class.getResourceAsStream("/beans.properties");
          Properties property = new Properties();
          property.load(in);
          //2.反射創(chuàng)建對(duì)象
          Set<Object> keySet = property.keySet();
          for (Object key : keySet) {
              // 2.1 獲取類的全路徑
              String classStr = (String) property.get(key);
              // 2.2 加載class 到虛擬機(jī)
              Class<?> beanClazz = Class.forName(classStr);
              // 2.3 獲取缺省的構(gòu)造函數(shù)
              Constructor<?> declaredConstructor = beanClazz.getDeclaredConstructor();
              // 2.4 創(chuàng)建實(shí)例
              Object o = declaredConstructor.newInstance();
              container.put((String) key,o);
          }
          // 3.獲取實(shí)例
          Npc npc = (Npc) container.get("npc");
          System.out.println(npc == null);
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
}

5、總結(jié)

在使用Java反射機(jī)制時(shí),主要步驟包括:

獲取 目標(biāo)類型的Class對(duì)象

通過 Class 對(duì)象分別獲取Constructor類對(duì)象、Method類對(duì)象 或者 Field 類對(duì)象

通過 Constructor類對(duì)象、Method類對(duì)象 & Field類對(duì)象分別獲取類的構(gòu)造函數(shù)、方法&屬性的具體信息,并進(jìn)行后續(xù)操作。

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • SpringBoot項(xiàng)目加入沖突動(dòng)態(tài)監(jiān)測(cè)算法的實(shí)現(xiàn)

    SpringBoot項(xiàng)目加入沖突動(dòng)態(tài)監(jiān)測(cè)算法的實(shí)現(xiàn)

    沖突動(dòng)態(tài)監(jiān)測(cè)算法是一種網(wǎng)絡(luò)通信中的沖突檢測(cè)方法,適用于無線網(wǎng)絡(luò)或其他共享傳輸介質(zhì)的環(huán)境,本文主要介紹了SpringBoot項(xiàng)目加入沖突動(dòng)態(tài)監(jiān)測(cè)算法的實(shí)現(xiàn),感興趣的可以了解一下
    2023-09-09
  • java實(shí)現(xiàn)抖音飛機(jī)大作戰(zhàn)

    java實(shí)現(xiàn)抖音飛機(jī)大作戰(zhàn)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)抖音飛機(jī)大作戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • springboot啟動(dòng)類如何剔除掃描某個(gè)包

    springboot啟動(dòng)類如何剔除掃描某個(gè)包

    這篇文章主要介紹了springboot啟動(dòng)類如何剔除掃描某個(gè)包,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • java中ImageReader和BufferedImage獲取圖片尺寸實(shí)例

    java中ImageReader和BufferedImage獲取圖片尺寸實(shí)例

    這篇文章主要介紹了java中ImageReader和BufferedImage獲取圖片尺寸實(shí)例,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • 基于feign傳參MultipartFile問題解決

    基于feign傳參MultipartFile問題解決

    這篇文章主要介紹了基于feign傳參MultipartFile問題解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java實(shí)現(xiàn)微信企業(yè)付款到個(gè)人

    java實(shí)現(xiàn)微信企業(yè)付款到個(gè)人

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)微信企業(yè)付款到個(gè)人功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • SpringBoot登錄用戶權(quán)限攔截器

    SpringBoot登錄用戶權(quán)限攔截器

    這篇文章主要介紹了SpringBoot登錄用戶權(quán)限攔截器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • SpringBoot處理form-data表單接收對(duì)象數(shù)組的方法

    SpringBoot處理form-data表單接收對(duì)象數(shù)組的方法

    form-data則是一種更加靈活的編碼方式,它可以處理二進(jìn)制數(shù)據(jù)(如圖片、文件等)以及文本數(shù)據(jù),這篇文章主要介紹了SpringBoot處理form-data表單接收對(duì)象數(shù)組,需要的朋友可以參考下
    2023-11-11
  • SpringBoot3和ShardingSphere5框架實(shí)現(xiàn)數(shù)據(jù)分庫分表

    SpringBoot3和ShardingSphere5框架實(shí)現(xiàn)數(shù)據(jù)分庫分表

    這篇文章主要介紹了SpringBoot3和ShardingSphere5框架實(shí)現(xiàn)數(shù)據(jù)分庫分表的相關(guān)資料,需要的朋友可以參考下
    2023-08-08
  • Spring AOP快速入門及開發(fā)步驟

    Spring AOP快速入門及開發(fā)步驟

    Spring AOP(面向切面編程)核心概念包括切面(Aspect)、連接點(diǎn)(JoinPoint)、切點(diǎn)(Pointcut)、通知(Advice)等,通過在不改變?cè)a的情況下,對(duì)方法進(jìn)行增強(qiáng),實(shí)現(xiàn)了代碼的解耦和功能擴(kuò)展,本文帶來大家掌握Spring 中 AOP 的開發(fā)步驟,感興趣的朋友一起看看吧
    2024-10-10

最新評(píng)論