反射 p5 反射相關使用和暴破

来源:https://www.cnblogs.com/zh-Note/archive/2023/07/25/17557512.html
-Advertisement-
Play Games

# **反射相關使用和暴破** ## **通過反射創建對象** 1. **方式一:**調用類中的public修飾的無參構造器; 2. **方式二:**調用類中的指定構造器; 3. **Class類相關方法:** - newInstance():調用類中的無參構造器,獲取對應類的對象; - getCo ...


反射相關使用和暴破

通過反射創建對象

  1. 方式一:調用類中的public修飾的無參構造器;
  2. 方式二:調用類中的指定構造器;
  3. Class類相關方法:
    • newInstance():調用類中的無參構造器,獲取對應類的對象;
    • getConstructor(Class...clazz):根據參數列表,獲取對應的public構造器對象;
    • getDecalaredConstructor(Class...clazz):根據參數列表,獲取對應的所有構造器對象;
  4. Constructor類相關方法:
    • setAccessible():暴破;
    • newInstance(Object...obj):調用構造器;

代碼演示:

package com.hspedu.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * @author: 86199
 * @date: 2023/6/5 20:32
 * @description: 演示通過反射機制創建實例
 */
public class ReflectCreateInstance {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //先獲取User類的Class對象
        Class<?> userClass = Class.forName("com.hspedu.reflection.User");
        //1. 通過public無參構造器構造實例
        Object user = userClass.newInstance();
        System.out.println("user = " + user);
        //2. 通過public有參構造器構造實例
        /*
            此時 constructor 對象就是這個構造器
            public User(String name){//public 的有參構造器
                this.name = name;
            }
         */
        //先得到對應的構造器
        Constructor<?> constructor = userClass.getConstructor(String.class);
        //創建實例,傳入實參
        Object user1 = constructor.newInstance("小花");
        System.out.println("user1 = " + user1);

        //3. 通過非public有參構造器構造實例
        //先得到對應的private構造器
        Constructor<?> declaredConstructor = userClass.getDeclaredConstructor(String.class, int.class);
        //創建實例
        declaredConstructor.setAccessible(true);//暴破【暴力破解】,使用反射可以訪問private構造器/方法/屬性,反射面前,都是紙老虎
        Object user2 = declaredConstructor.newInstance("小黑", 20);
        System.out.println("user2 = " + user2);
    }
}

class User{//User類
    //屬性
    private String name = "大黃";
    private int age = 10;

    public User() {//無參構造器
    }

    public User(String name){//public 的有參構造器
        this.name = name;
    }
    private User(String name, int age) {//private 有參構造器
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User [ age = " + age + ", name = " + name + " ]";
    }
}

/*運行結果
user = User [ age = 10, name = 大黃 ]
user1 = User [ age = 10, name = 小花 ]
user2 = User [ age = 20, name = 小黑 ]
*/

通過反射訪問類中成員

訪問屬性

  1. 根據屬性名獲取Field對象

    Field f = clazz對象.getDeclaredField(屬性名);//獲取所有

    Field f = clazz對象.getField(屬性名);//獲取公有

  2. 暴破:f.setAccessible(true)//f 是Field

  3. 訪問

    f.set(o, 值) //o 表示本類的對象
    System.out.println(f.get(o));//o 表示對象
    
  4. 註意:如果是靜態屬性,則set和get中的參數o,可以寫成null;

代碼演示:

package com.hspedu.reflection;

import java.lang.reflect.Field;

/**
 * @author: 86199
 * @date: 2023/6/5 21:37
 * @description: 演示反射操作屬性
 */
public class ReflectAccessProperty {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //得到Student類對應的Class對象
        Class<?> stuClass = Class.forName("com.hspedu.reflection.Student");
        //創建對象
        Object o = stuClass.newInstance();//o 的運行類型就是Student
        System.out.println(o.getClass());//class com.hspedu.reflection.Student

        //1. 使用反射得到age屬性對象
        Field age = stuClass.getField("age");//拿到公有的
        age.set(o, 88);//通過反射操作屬性
        System.out.println(o);
        System.out.println(age.get(o));//返回age的值

        //2. 使用反射操作name屬性
        Field name = stuClass.getDeclaredField("name");
        name.setAccessible(true);//對name進行暴破,可以操作私有屬性
        //name.set(o, "大黑");
        name.set(null, "大白");//因為name是static修飾的,所以這裡 o 也可以寫成 null
        System.out.println(o);
        System.out.println(name.get(o));//獲取屬性值
        System.out.println(name.get(null));//只有靜態的才能這樣用
    }
}
class Student{//類
    public int age;
    private static String name;

    public Student() {
    }

    @Override
    public String toString() {
        return "Student [ " +
                "age = " + age + " name = " + name +
                ']';
    }
}
/*	運行結果
class com.hspedu.reflection.Student
Student [ age = 88 name = null]
88
Student [ age = 88 name = 大白]
大白
大白
*/

訪問方法

  1. 根據方法名和參數列表獲取Method方法對象:

    Method m = clazz.getDeclaredMethod(方法名, XX.class);//得到本類的所有方法

    Method m = clazz.getMethod(方法名, XX.class);//得到本類的public方法

  2. 暴破:m.setAccessible(true);

  3. 訪問:Object returnVal = m.invoke(o, 實參列表);//o就是本類的對象

  4. 註意:如果是靜態方法,則invoke的參數o,可以寫成null;

代碼演示:

package com.hspedu.reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author: 86199
 * @date: 2023/6/5 21:56
 * @description: 演示通過反射調用方法
 */
public class ReflectAccessMethod {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, InvocationTargetException, NoSuchMethodException {
        //獲取Boss類的Class對象
        Class<?> bossCls = Class.forName("com.hspedu.reflection.Boss");
        //創建對象
        Object o = bossCls.newInstance();
        //1. 調用public 的 hi 方法
        //得到hi方法對象
//        Method hi = bossCls.getMethod("hi", String.class);//OK
        Method hi = bossCls.getDeclaredMethod("hi", String.class);//OK
        hi.invoke(o, "大黃!");
        //2. 調用private的say方法
        //得到say方法對象
        Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class);
        //因為say方法私有,所以需要先暴破
        say.setAccessible(true);
        System.out.println(say.invoke(o, 20, "張三", '男'));

        //3. 因為say方法是static,所以可以這樣調用
        System.out.println(say.invoke(null, 18, "李四", '女'));

        //返回值,在反射中如果方法有返回值統統返回Object,但是運行類型和方法定義的返回類型相同
        //如果返回類型是void,返回null也是Object類型
        Object reVal = say.invoke(null, 23, "王五", '男');
        System.out.println("reVal的運行類型" + reVal.getClass());
    }
}

class Boss{//類
    public int age;
    private static String name;

    public Boss() {//構造器
    }

    private static String say(int n, String s, char c){//靜態方法
        return n + " " + s + " " + c;
    }

    public void hi(String s){//普通方法
        System.out.println("hi " + s);
    }
}

/* 運行結果
hi 大黃!
20 張三 男
18 李四 女
reVal的運行類型class java.lang.String
*/

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

-Advertisement-
Play Games
更多相關文章
  • ## 🏰 腳手架文件結構 """ ├── node_modules ├── public │ ├── favicon.ico: 頁簽圖標 │ └── index.html: 主頁面 ├── src │ ├── assets: 存放靜態資源 │ │ └── logo.png │ │── compon ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 從computed的特性出發 computed最耀眼的幾個特性是啥? 1. 依賴追蹤 import { reactive, computed } from 'vue' const state = reactive({ a: 1, b: 2 ...
  • #【後端面經-Spring】Spring簡介 [TOC](【後端面經-Spring】Spring簡介) ## 1. Spring簡介 Spring是為了簡化java項目開發設計的一款設計層面開源框架,其設計目的就是為了“簡化開發”。 它使用分層架構,解決業務邏輯層和各層之間的松耦合。 核心特性: - ...
  • antv-x6是一個功能強大、可擴展性高的可視化工具,提供了一系列開箱即用的交互軟體和簡單易用的節點定製能力,能夠幫助使用者便捷地創建流程圖、ER圖等交互性較強的應用。本次分享介紹了x6的基本功能,更多高級功能有待我們進一步學習和探索。 ...
  • 高可用的三大利器是熔斷、限流和降級。它們都是在分散式系統中用於保障系統穩定性和可用性的重要策略。熔斷(Circuit Breaker):熔斷是一種防止故障擴散的機制。當一個服務出現故障或超時,熔斷器會打開並快速失敗,拒絕後續的請求,避免請求堆積和資源耗盡。熔斷器會暫時屏蔽該服務,併在一段時間後嘗試恢... ...
  • Docker CLI (命令行界面) 是一個強大的工具,可讓您與 Docker 容器、映像、捲和網路進行交互和管理。它為用戶提供了廣泛的命令,用於在其開發和生產工作流中創建、運行和管理 Docker 容器和其他 Docker 資源。 ### 安裝 要開始使用 Docker CLI,您需要在電腦上安 ...
  • # 未定義行為之 NULL dereference 下麵這段代碼中 `is_valid()` 解引用了空指針 `str`,我們的直覺是編譯運行後將迎來 SIGSEGV,然而事情並非所期望的那樣。 ```c /* * ub_null.c - 未定義行為演示 之 NULL dereference */ ...
  • 本專題寫作的目的其實是分享go語言編程的使用場景,介紹go語言編程的方方面面,讓大家能夠用好這個由google公司發明的強力工具,提升大家在這方面的生產力,畢竟**”君子善假與物也“**嘛。 這裡我先說明一下,我並不是一個對go語言的所有一切都認同的人,你會發現很多相關從業者也會吐槽go語言的“專制 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...