検索
ホームページJava&#&チュートリアルJava デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します

この記事では、java のリフレクション機構に関する問題を中心に、Java に関する知識をお届けします Java 言語のプログラム情報を動的に取得したり、オブジェクトを動的に呼び出す機能をリフレクションといいます。 , 皆様のお役に立てれば幸いです。

Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します

推奨される学習: 「java チュートリアル

偉い人の話を聞いたり、フォーラムやその他の学習方法を見るたびにjavaの脆弱性を逆シリアル化する際に、リフレクションメカニズムという言葉があります。上司はこの言葉を使ってペイロードを作成します。Javaの逆シリアル化を学んだばかりの人にとっては、少し混乱するかもしれません。とにかく、私は混乱しています。それで私はすぐに教訓を学びました。そうしないと、私と偉い人たちとの差はますます広がってしまいます。したがって、この記事では主に Java リフレクション メカニズムについて説明します

Java リフレクション メカニズム

Java のリフレクション (リフレクション) メカニズムとは、プログラムの実行状態で、任意のクラスのオブジェクトを構築できることを意味します。理解できる 任意のオブジェクトが属するクラスは、任意のクラスのメンバー変数とメソッドを理解でき、任意のオブジェクトのプロパティとメソッドを呼び出すことができます。この動的にプログラム情報を取得し、動的にオブジェクトを呼び出す機能をJava言語のリフレクション機構と呼びます。リフレクションは動的言語の鍵とみなされます。

私は言葉で表現するのがあまり得意ではないので、上の写真を例にしてみましょう

反射機構なし

//定义一个animals接口interface animals {
    public abstract void print();}//定义类来实现animals接口的抽象方法class Dog implements animals {
    public void print() {
        System.out.println("Dog");
    }}class Cat implements animals {
    public void print() {
        System.out.println("Cat");
    }}// 构造一个zoo类// 之后如果我们在添加其他的实例的时候只需要修改zoo类class zoo {

    public static animals getInstance(String animalsName) {
        animals a = null;
        if ("Dog".equals(animalsName)) {
            a = new Dog();
        }
        if ("Cat".equals(animalsName)) {
            a = new Cat();
        }
        return a;
    }}public class reflection {
    public static void main(String[] args) {
        //借助zoo类寻找对应的类来实现接口
        animals a=zoo.getInstance("Cat");
        if(a!=null)
            a.print();
    }}

この時点で動物を追加するには、 just

  • クラスを追加
  • zooを変更
  • #main関数のanimalクラスを変更
  • ##上記をリフレクション機構に変更
//定义一个animals接口interface animals {
    public abstract void print();}//定义类来实现animals接口的抽象方法class Dog implements animals {
    public void print() {
        System.out.println("Dog");
    }}class Cat implements animals {
    public void print() {
        System.out.println("Cat");
    }}// 构造一个zoo类// 之后如果我们在添加其他的实例的时候只需要修改zoo类class zoo {

    public static animals getInstance(String className) {
        animals a = null;
        try {
            //借助Class.forName寻找类名,并用newInstance实例化类似于new
            a = (animals) Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return a;
    }}public class reflection {
    public static void main(String[] args) {
        //借助zoo类寻找对应的类来实现接口(classname为当前包名加类名)
        animals a = zoo.getInstance("com.cc1.Dog");
        if (a != null)
            a.print();
    }}

この時点で動物を追加する必要があるのは、

クラスを追加する
  • メイン関数の動物クラスを変更する
  • ステップが節約され、受信クラス名は制御可能で、存在しているように見えます。 クラスは調整できます。

#リフレクション メカニズムのメソッド

#私たちが最もよく使用するものは、おそらく

## です。 #forName (クラスの呼び出し)

    getMethod (以下のクラスメソッドの呼び出し)
  • invoke (実行)
  • newInstance (インスタンス化されたオブジェクト)
Class.forName(className).getMethod(methodName).invoke(Class.forName(className).newInstance());
  • 以下では、リフレクション メカニズムを使用して、コンピューター (calc) またはメモ帳 (notepad) をポップアップ表示します
  • コンピューターにはたくさんのポップアップがあるため、今回はメモ帳だけを再生します。ポップアップできるのは素晴らしいことです

    Runtime.getRuntime().exec("notepad");

    getRuntime 関数を見てみましょう

    Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します
    この関数がランタイムのための方法であることを学びましたオブジェクトを取得するためのクラスです 個人的には毎回呼び出すのが面倒に感じます オブジェクト作成のために一度呼び出さないように関数にカプセル化しています
    Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します
    クラスの取得方法object

    Class.forName (クラス名を取得)

      zoo.class (ロード済みのクラス)
    • obj .class (インスタンス)

    • Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します#クラスの初期化

    Zoo クラスを変更し、初期ブロック、静的初期ブロック、コンストラクターを追加します

    class zoo {
        //初始块
        {
            System.out.println("1  " + this.getClass());
        }
    
        //静态初始块
        static {
            System.out.println("2  " + zoo.class);
        }
    
        public zoo() {
            System.out.println("3  " + this.getClass());
        }
    
        public static animals getInstance(String className) {
            animals a = null;
            try {
                //借助Class.forName寻找类名,并用newInstance实例化类似于new
                a = (animals) Class.forName(className).newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return a;
        }}

    クラス初期化実行シーケンス

    : 静的初期ブロック

    クラスインスタンス化実行シーケンス
    : 静的初期ブロック→初期ブロック→コンストラクターJava デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します
    このことから、クラスの初期化とクラスのインスタンス化は異なることがわかります
    Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します
    次に、zoo1 クラスを追加して、zoo クラスを継承します

    class zoo1 extends zoo{
        //初始块
        {
            System.out.println("11  " + this.getClass());
        }
    
        //静态初始块
        static {
            System.out.println("12  " + zoo.class);
        }
    
        public zoo1() {
            System.out.println("13  " + this.getClass());
        }}

    サブクラスの初期化シーケンス

    : 親クラスの静的初期化ブロック - > サブクラスの静的初期化ブロック

    #サブクラスのインスタンス化シーケンス
    : 親クラスの静的初期化ブロック - > サブクラスの静的初期化ブロック - >親クラスの初期化ブロック - > 親クラスのコンストラクター - > サブクラスの初期化ブロック - > サブクラスのコンストラクターJava デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します
    # #上記のことから、Class.forName が使用され、クラスが静的初期化ブロックは制御可能であり、任意のコードを実行できます。
    Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します#内部クラスの呼び出し
    #Class.forName("java.lang.Runtime" ) クラスを取得します (java.lang.Runtime は Runtime クラスのフルパスです)

    getMethod

    getMethod の関数は次のとおりです。リフレクションを通じてクラスの特定のパブリック メソッドを取得します。
    Java はクラスのオーバーロードをサポートしていますが、関数は関数名だけでは決定できないため、getMethod を呼び出すときは、パラメーターの型のリストをそのメソッドに渡す必要があります。

    Class.forName("java.lang.Runtime ") .getMethod(“exec”, String.class)

    invoke


    静态和动态方法的区别
    Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します

    invoke方法在getMethod类下,作用时传递参数,执行方法
    public Object invoke(Object obj, Object… args)
    第一个参数是getMethod获取的方法的类对象(如果方法是静态方法则传类)
    获取exec函数的类对象
    Class.forName(“java.lang.Runtime”).getMethod(“getRuntime”).invoke(Class.forName(“java.lang.Runtime”))
    由于getRuntime是静态方法,所以传类
    invoke(Class.forName(“java.lang.Runtime”).getMethod(“getRuntime”).invoke(Class.forName(“java.lang.Runtime”)),“calc.exe”)

    最后我们合并一下

    Class.forName("java.lang.Runtime").
                    getMethod("exec", String.class).
                    invoke(Class.forName("java.lang.Runtime").getMethod("getRuntime").invoke(Class.forName("java.lang.Runtime")), "notepad");

    Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します

    指定构造方法生成实例

    String str="notepad";ProcessBuilder pb = new ProcessBuilder(str);pb.start();

    getConsturctor(函数可以选定指定接口格式的构造函数(由于构造函数也可以根据参数来进行重载)
    选定后我们可以通过newInstance(),并传入构造函数的参数执行构造函数

    ProcessBuilder类有两个构造函数

    • public ProcessBuilder(String… command)(String…变长的字符串数组String[].class)
    • public ProcessBuilder(List command)

    分别使用构造方法

    • Class.forName(“java.lang.ProcessBuilder”).getConstructor(String[].class).newInstance(new String[][]{{“notepad”}})
    • Class.forName(“java.lang.ProcessBuilder”).getConstructor(List.class).newInstance(Arrays.asList(“notepad”))

    执行完构造方法实例后,在进行强制转化使用start函数即可

    ( (ProcessBuilder) Class.forName(“java.lang.ProcessBuilder”).getConstructor(List.class).newInstance(Arrays.asList(“notepad”))).start();

    实际中,肯定用不了,哪有这么好的事,还是接着反射把

    Class.forName(“java.lang.ProcessBuilder”).getMethod(“start”).invoke(clazz.getConstructor(List.class).newInstance(Arrays.asList(“notepad”)));
    Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します
    这里可能有人会好奇我写的里那的另一个构造函数,String…command这个传参为什么用new String[][]{{“notepad”}},不应该是new String[]{“notepad”},现在用应该的

    ((ProcessBuilder) Class.forName(“java.lang.ProcessBuilder”).getConstructor(String[].class).newInstance(new String[]{“notepad”})).start();

    在这行打断点调试
    Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します
    我们传的是一个字符串数组到了实例化的时候变成了一个字符串,再看看另一个构造函数(List)

    ( (ProcessBuilder) Class.forName(“java.lang.ProcessBuilder”).getConstructor(List.class).newInstance(Arrays.asList(“notepad”))).start();

    依旧还是这行打断点

    Java デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明します
    由此可知,List传入时会被当作Object的第一项,而String[]会被当做Object,所以多加一层[]{}

    执行私有方法

    通过函数getDeclaredConstructor获取私有方法,再利用setAccessible(true)打破私有方法限制

    Class cls = Class.forName("java.lang.Runtime"); 
    Constructor m = cls.getDeclaredConstructor();
     m.setAccessible(true); 
     cls.getMethod("exec", String.class).invoke(m.newInstance(), "notepad");

     推荐学习:《java视频教程

    以上がJava デシリアライゼーションのリフレクション メカニズムを例とともに詳しく説明しますの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明
    この記事はCSDNで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
    JVMはオペレーティングシステムAPIの違いをどのように処理しますか?JVMはオペレーティングシステムAPIの違いをどのように処理しますか?Apr 27, 2025 am 12:18 AM

    JVMは、JavanativeInterface(JNI)およびJava Standard Libraryを介してオペレーティングシステムのAPIの違いを処理します。1。JNIでは、Javaコードがローカルコードを呼び出し、オペレーティングシステムAPIと直接対話できます。 2. Java Standard Libraryは統一されたAPIを提供します。これは、異なるオペレーティングシステムAPIに内部的にマッピングされ、コードがプラットフォーム間で実行されるようにします。

    Java 9で導入されたモジュール性は、プラットフォームの独立性にどのように影響しますか?Java 9で導入されたモジュール性は、プラットフォームの独立性にどのように影響しますか?Apr 27, 2025 am 12:15 AM

    modularitydoesnotdirectlyectlyectjava'splatformindepensence.java'splatformendepenceismaindainededainededainededaindainedaindained bythejvm、butmodularityinfluencesApplucationStructure andmanagement、間接的なインパクチャプラット形成依存性.1)

    ByteCodeとは何ですか?また、Javaのプラットフォームの独立性とどのように関係していますか?ByteCodeとは何ですか?また、Javaのプラットフォームの独立性とどのように関係していますか?Apr 27, 2025 am 12:06 AM

    bytecodeinjavaisthe intermediaterepresentationthateNablesplatformindepence.1)javacodeis compiledintobytecodestoredin.classfiles.2)thejvminterpretsorcompilesthisbytecodeintomachinecodeatime、

    Javaがプラットフォームに依存しない言語と見なされるのはなぜですか?Javaがプラットフォームに依存しない言語と見なされるのはなぜですか?Apr 27, 2025 am 12:03 AM

    javaachievesplatformedenceTheTheTheJavavirtualMachine(JVM)、これは、javacodeisisisisisissompiledIntobytecode.2)javaCodeisisisisissompiledevedevicetecode.2)

    グラフィカルユーザーインターフェイス(GUI)は、Javaのプラットフォーム独立性の課題をどのように提示できますか?グラフィカルユーザーインターフェイス(GUI)は、Javaのプラットフォーム独立性の課題をどのように提示できますか?Apr 27, 2025 am 12:02 AM

    Javagui開発におけるプラットフォームの独立性は課題に直面していますが、Swing、Javafx、統一外観、パフォーマンス最適化、サードパーティライブラリ、クロスプラットフォームテストを使用することで対処できます。 Javaguiの開発は、クロスプラットフォームの一貫性を提供することを目的としたAWTとSwingに依存していますが、実際の効果はオペレーティングシステムごとに異なります。ソリューションには以下が含まれます。1)SwingおよびJavafxをGUIツールキットとして使用します。 2)uimanager.setlookandfeel()を介して外観を統合します。 3)さまざまなプラットフォームに合わせてパフォーマンスを最適化します。 4)ApachepivotやSWTなどのサードパーティライブラリを使用する。 5)一貫性を確保するために、クロスプラットフォームテストを実施します。

    Java開発のどの側面がプラットフォームに依存していますか?Java開発のどの側面がプラットフォームに依存していますか?Apr 26, 2025 am 12:19 AM

    javadevelopmentisnotentirelylylypratform-IndopentDuetoseveralfactors.1)jvmvariationsaffectperformanceandbehavioracrossdifferentos.2)nativeLibrariesviajniintroducePlatform-specificissues.3)giaiasystemsdifferbeTioneplateplatifflics.4)

    さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?さまざまなプラットフォームでJavaコードを実行するときにパフォーマンスの違いはありますか?なぜ?Apr 26, 2025 am 12:15 AM

    Javaコードは、さまざまなプラットフォームで実行するときにパフォーマンスの違いがあります。 1)JVMの実装と最適化戦略は、OracleJDKやOpenJDKなどとは異なります。 2)メモリ管理やスレッドスケジューリングなどのオペレーティングシステムの特性もパフォーマンスに影響します。 3)適切なJVMを選択し、JVMパラメーターとコード最適化を調整することにより、パフォーマンスを改善できます。

    Javaのプラットフォームの独立性の制限は何ですか?Javaのプラットフォームの独立性の制限は何ですか?Apr 26, 2025 am 12:10 AM

    java'splatformindepentedencehaslimitationsincludingporformanceoverhead、versioncompatibulisisues、changleSwithnativeLibraryIntegration、プラットフォーム固有の機能、およびjvminStallation/maintenation。

    See all articles

    ホットAIツール

    Undresser.AI Undress

    Undresser.AI Undress

    リアルなヌード写真を作成する AI 搭載アプリ

    AI Clothes Remover

    AI Clothes Remover

    写真から衣服を削除するオンライン AI ツール。

    Undress AI Tool

    Undress AI Tool

    脱衣画像を無料で

    Clothoff.io

    Clothoff.io

    AI衣類リムーバー

    Video Face Swap

    Video Face Swap

    完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

    ホットツール

    VSCode Windows 64 ビットのダウンロード

    VSCode Windows 64 ビットのダウンロード

    Microsoft によって発売された無料で強力な IDE エディター

    SublimeText3 Linux 新バージョン

    SublimeText3 Linux 新バージョン

    SublimeText3 Linux 最新バージョン

    メモ帳++7.3.1

    メモ帳++7.3.1

    使いやすく無料のコードエディター

    SublimeText3 中国語版

    SublimeText3 中国語版

    中国語版、とても使いやすい

    mPDF

    mPDF

    mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。