Table des matières
Réflexion
Définition de réflexion
Utilisation de base de la réflexion
1. Obtenez l'objet de classe
une méthode forName()
b. Obtenez directement
c. getClass()方法
d. getSystemClassLoader().loadClass()方法
2. 获取类方法
a. getDeclaredMethods
b. getDeclaredMethod
c. getMethods
d. getMethod
3. 获取成员变量
a. getDeclaredFields
b. getDeclaredField(String name)
c. getFields()
d. getField(String name)
4. 获取构造函数Constructor
5. 反射创建类对象
newInstance
invoke
Runtime的rce例子(访问限制突破)
后记
Maison Java javaDidacticiel Comment utiliser la réflexion et l'analyse d'exemples Java

Comment utiliser la réflexion et l'analyse d'exemples Java

May 06, 2023 pm 04:31 PM
java

    Réflexion

    Définition de réflexion

    Un objet peut obtenir sa classe par réflexion, et une classe peut obtenir toutes les méthodes (y compris privées) par réflexion. Les fichiers de bytecode peuvent être exploités et lus via le mécanisme de réflexion dans le langage Java. .Et modifiez le fichier de bytecode

    Utilisation de base de la réflexion

    1. Obtenez l'objet de classe

    une méthode forName()

    Vous avez seulement besoin de connaître le nom de la classe, et l'exemple de code sera utilisé lors du chargement de JDBC

    .
    public class test1 {
        public static void main(String[] args) throws ClassNotFoundException {
            Class name = Class.forName("java.lang.Runtime");
            System.out.println(name);
        }
    }
    Copier après la connexion

    Comment utiliser la réflexion et lanalyse dexemples Java

    b. Obtenez directement

    Utilisez .class pour obtenir l'objet .class去获取对于的对象

    public class test1 {
        public static void main(String[] args) throws ClassNotFoundException {
            Class<?> name = Runtime.class;
            System.out.println(name);
        }
    }
    Copier après la connexion
    c. getClass()方法

    getClass来获取字节码对象,必须要明确具体的类,然后创建对象

    public class test1 {
        public static void main(String[] args) throws ClassNotFoundException {
            Runtime rt = Runtime.getRuntime();
            Class<?> name = rt.getClass();
            System.out.println(name);
        }
    }
    Copier après la connexion
    d. getSystemClassLoader().loadClass()方法

    这个方法和forName类似,只要有类名就可以了,但是区别在于,forName的静态JVM会装载类,并执行static()中的代码

    public class getSystemClassLoader {
        public static void main(String[] args) throws ClassNotFoundException {
            Class<?> name = ClassLoader.getSystemClassLoader().loadClass("java.lang.Runtime");
            System.out.println(name);
        }
    }
    Copier après la connexion

    2. 获取类方法

    a. getDeclaredMethods

    返回类或接口声明的所有方法,包括public、protected、private和默认方法,但是不包括继承的方法

    import java.lang.reflect.Method;
    
    public class getDeclaredMethods {
        public static void main(String[] args) throws ClassNotFoundException {
            Class<?> name = Class.forName("java.lang.Runtime");
            System.out.println(name);
            Method[] m = name.getDeclaredMethods();
            for(Method x:m)
                System.out.println(x);
        }
    }
    Copier après la connexion

    Comment utiliser la réflexion et lanalyse dexemples Java

    b. getDeclaredMethod

    获取特定的方法,第一个参数是方法名,第二个参数是该方法的参数对应的class对象,例如这里Runtime的exec方法参数为一个String,所以这里的第二个参数是String.class

    import java.lang.reflect.Method;
    
    public class getDeclaredMethod {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
            Class<?> name = Class.forName("java.lang.Runtime");
            Method m = name.getDeclaredMethod("exec",String.class);
            System.out.println(m);
        }
    }
    Copier après la connexion
    c. getMethods

    返回某个类所有的public方法,包括继承类的public方法

    d. getMethod

    参数同理getDeclaredMethod

    3. 获取成员变量

    同理Method的那几个方法

    a. getDeclaredFields

    获取类的成员的所有变量数组,但是不包括父类的

    b. getDeclaredField(String name)

    获取特定的,参数是想要的方法的名称

    c. getFields()

    同理,只能获得public的,但是包括了父类的

    d. getField(String name)

    同理,参数是想要的方法的名称

    4. 获取构造函数Constructor

    Constructor[] getConstructors() :只返回public构造函数

    Constructor[] getDeclaredConstructors() :返回所有构造函数

    Constructor<> getConstructor(类... parameterTypes) : 匹配和参数配型相符的public构造函数

    Constructor<> getDeclaredConstructor(类... parameterTypes) : 匹配和参数配型相符的构造函数

    后面两个方法的参数是对于方法的参数的类型的class对象,和Method的那个类似,例如String.class

    5. 反射创建类对象

    newInstance

    可以通过反射来生成实例化对象,一般我们使用Class对象的newInstance()方法来进行创建类对象

    创建的方法就是:只需要通过forname方法获取到的class对象中进行newInstance方法创建即可

    Class c = Class.forName("com.reflect.MethodTest"); // 创建Class对象
    Object m1 =  c.newInstance(); // 创建类对象
    Copier après la connexion
    invoke

    invoke方法位于java.lang.reflect.Method类中,用于执行某个的对象的目标方法,一般会和getMethod方法配合进行调用。

    使用用法:

    public Object invoke(Object obj, Object... args)
    Copier après la connexion

    第一个参数为类的实例,第二个参数为相应函数中的参数

    obj:从中调用底层方法的对象,必须是实例化对象

    args: 用于方法的调用,是一个object的数组,参数有可能是多个

    但需要注意的是,invoke方法第一个参数并不是固定的:

    • 如果调用这个方法是普通方法,第一个参数就是类对象;

    • 如果调用这个方法是静态方法,第一个参数就是类;

    通过一个例子去理解

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Invoke {
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class c = Class.forName("Invoke");
            Object o = c.newInstance();
            Method m = c.getMethod("test");
            m.invoke(o);
        }
        public void test(){
            System.out.println("测试成功");
        }
    }
    Copier après la connexion

    Comment utiliser la réflexion et lanalyse dexemples Java

    简单来说就是这样

    方法.invoke(类或类对象)

    先forName拿到Class,再newInstance获取类对象,再getMethod获取方法,然后调用

    Runtime的rce例子(访问限制突破)

    Runtime类里面有一个exec方法,可以执行命令

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Exec {
        public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            Class c = Class.forName("java.lang.Runtime");
            Object o = c.newInstance();
            Method m = c.getMethod("exec",String.class);
            m.invoke(o,"/System/Applications/Calculator.app/Contents/MacOS/Calculator");
        }
    }
    Copier après la connexion

    但是发现报错了

    Comment utiliser la réflexion et lanalyse dexemples Java

    出现这个问题的原因:

    • 使用的类没有无参构造函数

    • 使用的类构造函数是私有的

    那么解决方案就是setAccessible(true);

    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Exec {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
            Class c = Class.forName("java.lang.Runtime");
            Constructor con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Method m = c.getMethod("exec",String.class);
            m.invoke(con.newInstance(),"/System/Applications/Calculator.app/Contents/MacOS/Calculator");
        }
    }
    Copier après la connexion
    Copier après la connexion

    c méthode getClass() 🎜🎜getClass pour obtenir l'objet bytecode, vous devez spécifier la classe spécifique, puis créez l'objet 🎜
    import java.lang.reflect.Constructor;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    public class Exec {
        public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
            Class c = Class.forName("java.lang.Runtime");
            Constructor con = c.getDeclaredConstructor();
            con.setAccessible(true);
            Object o = con.newInstance();
            Method m = c.getMethod("exec",String.class);
            m.invoke(o,"/System/Applications/Calculator.app/Contents/MacOS/Calculator");
        }
    }
    Copier après la connexion
    Copier après la connexion
    🎜d. Méthode getSystemClassLoader().loadClass()🎜🎜Cette méthode est similaire à forName, tant qu'il y a un nom de classe, mais la différence est que la JVM statique de forName chargera la classe. et exécutez le code dans static()🎜 rrreee🎜2. Obtenez les méthodes de classe🎜🎜a. getDeclaredMethods🎜🎜Renvoie toutes les méthodes déclarées par la classe ou l'interface, y compris les méthodes publiques, protégées, privées et par défaut, mais n'inclut pas les méthodes héritées🎜. rrreee🎜Analyse d'exemples de méthodes d'application de réflexion Java🎜🎜b. getDeclaredMethod🎜🎜Obtenez la méthode spécifique, le premier paramètre est le nom de la méthode et le deuxième paramètre est l'objet de classe correspondant au paramètre de la méthode Par exemple, le paramètre de la méthode exec du Runtime est ici une chaîne, donc le deuxième paramètre. voici String.class🎜rrreee🎜c. getMethods🎜🎜 renvoie un certain Toutes les méthodes publiques d'une classe, y compris les méthodes publiques des classes héritées 🎜🎜d getMethod 🎜🎜 les paramètres sont les mêmes que getDeclaredMethod 🎜🎜 3. Obtenez les variables membres 🎜. 🎜 sont identiques à la méthode 🎜🎜a. getDeclaredFields 🎜🎜 récupère la classe Tous les tableaux de variables de membres, mais à l'exclusion de ceux de la classe parent 🎜🎜b getDeclaredField(String name)🎜🎜Get un paramètre spécifique est le nom du. méthode souhaitée 🎜🎜c.getFields()🎜🎜De même, il ne peut que devenir public, mais inclure le 🎜🎜d getField(String name)🎜🎜De même, le paramètre est le nom de la méthode souhaitée🎜🎜4. Obtenez le constructeur Constructor🎜
    🎜Constructor [] getConstructors() : renvoie uniquement les constructeurs publics🎜🎜Constructor[] getDeclaredConstructors() : renvoie tous les constructeurs🎜🎜Constructor<> ?>... ParameterTypes) : correspond au constructeur public qui correspond au type de paramètre🎜🎜Constructor<> getDeclaredConstructor(class... ParameterTypes) : correspond au constructeur qui correspond au type de paramètre🎜
    🎜Les paramètres des deux dernières méthodes sont Le type d'objet de classe pour les paramètres de méthode est similaire à celui de Method, tel que String.class🎜🎜5 La réflexion crée des objets de classe🎜🎜newInstance🎜🎜Vous. peut générer des objets instanciés par réflexion, généralement Nous utilisons la méthode newInstance() de l'objet Class pour créer l'objet de classe🎜🎜La méthode de création est la suivante : créez simplement la méthode newInstance dans l'objet de classe obtenu via la méthode forname🎜rrreee🎜invoke🎜 🎜La méthode d'invocation se trouve dans la classe java.lang.reflect.Method et est utilisée pour exécuter la méthode cible d'un certain objet. Elle est généralement appelée en conjonction avec la méthode getMethod. 🎜🎜Utilisation : 🎜rrreee🎜Le premier paramètre est l'instance de la classe, le deuxième paramètre est le paramètre dans la fonction correspondante🎜🎜obj : l'objet à partir duquel la méthode sous-jacente est appelée doit être un objet instancié🎜🎜args : utilisé pour les méthodes L'appel est un tableau d'objets, et les paramètres peuvent être multiples 🎜🎜Mais il faut noter que le premier paramètre de la méthode Invocation n'est pas fixe : 🎜
      < li> 🎜Si l'appel de cette méthode est une méthode normale, le premier paramètre est l'objet de classe ; 🎜
    • 🎜Si l'appel de cette méthode est une méthode statique, le premier paramètre est la classe ; 🎜🎜Passez un exemple pour comprendre🎜rrreee🎜Analyse d'exemples d'utilisation de Java réflexion🎜🎜 Pour faire simple, ça y est🎜
      🎜Method.invoke (classe ou objet de classe)🎜
      🎜Obtenez d'abord la classe forName, puis obtenez l'objet de classe avec newInstance, puis obtenez la méthode avec getMethod, puis appelez l'exemple rce de 🎜🎜Runtime (Percée des restrictions d'accès) 🎜🎜 Il existe une méthode exec dans la classe Runtime, qui peut exécuter des commandes 🎜rrreee🎜 Mais j'ai trouvé une erreur 🎜🎜Analyse d'exemples de méthodes d'application de réflexion Java🎜🎜La raison de ce problème : 🎜< ul class=" list-paddingleft-2">
    • 🎜La classe utilisée n'a pas de paramètres Constructeur🎜
    • 🎜Le constructeur de classe utilisé est privé🎜
    • 🎜🎜Ensuite, la solution est setAccessible(true);, utilisez-le pour briser les restrictions d'accès🎜

      Java.lang.reflect.AccessibleObject类是Field,Method和Constructor类对象的基类,可以提供将反射对象标记为使用它抑制摸人Java访问控制检查的功能,同时上述的反射类中的Field,Method和Constructor继承自AccessibleObject。所以我们在这些类方法基础上调用setAccessible()方法,既可对这些私有字段进行操作

      简单来说,私有的属性、方法、构造方法,可以通过这个去突破限制,xxx.setAccessible(true) 可以看到Runtime的构造方法是private的

      Comment utiliser la réflexion et lanalyse dexemples Java

      那么这里我们就可以这么去突破限制 先获取构造方法,然后setAccessible获取访问权限 然后再最后invoke里面,第一个参数写成con.newInstance()

      import java.lang.reflect.Constructor;
      import java.lang.reflect.InvocationTargetException;
      import java.lang.reflect.Method;
      
      public class Exec {
          public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
              Class c = Class.forName("java.lang.Runtime");
              Constructor con = c.getDeclaredConstructor();
              con.setAccessible(true);
              Method m = c.getMethod("exec",String.class);
              m.invoke(con.newInstance(),"/System/Applications/Calculator.app/Contents/MacOS/Calculator");
          }
      }
      Copier après la connexion
      Copier après la connexion

      Comment utiliser la réflexion et lanalyse dexemples Java

      这里有一个疑问,如果把con.newInstance单独提取出来,他打开计算器不会显示出来,但是后台的确是启动了,不知道啥原因

      import java.lang.reflect.Constructor;
      import java.lang.reflect.InvocationTargetException;
      import java.lang.reflect.Method;
      
      public class Exec {
          public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
              Class c = Class.forName("java.lang.Runtime");
              Constructor con = c.getDeclaredConstructor();
              con.setAccessible(true);
              Object o = con.newInstance();
              Method m = c.getMethod("exec",String.class);
              m.invoke(o,"/System/Applications/Calculator.app/Contents/MacOS/Calculator");
          }
      }
      Copier après la connexion
      Copier après la connexion

      后记

      反射中常用的几个重要方法:

      • 获取类的⽅法: forName

      • 实例化类对象的⽅法: newInstance

      • 获取函数的⽅法: getMethod

      • 执⾏函数的⽅法: invoke

      • 限制突破方法:setAccessible

      Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

    Déclaration de ce site Web
    Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

    Outils d'IA chauds

    Undresser.AI Undress

    Undresser.AI Undress

    Application basée sur l'IA pour créer des photos de nu réalistes

    AI Clothes Remover

    AI Clothes Remover

    Outil d'IA en ligne pour supprimer les vêtements des photos.

    Undress AI Tool

    Undress AI Tool

    Images de déshabillage gratuites

    Clothoff.io

    Clothoff.io

    Dissolvant de vêtements AI

    Video Face Swap

    Video Face Swap

    Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

    Outils chauds

    Bloc-notes++7.3.1

    Bloc-notes++7.3.1

    Éditeur de code facile à utiliser et gratuit

    SublimeText3 version chinoise

    SublimeText3 version chinoise

    Version chinoise, très simple à utiliser

    Envoyer Studio 13.0.1

    Envoyer Studio 13.0.1

    Puissant environnement de développement intégré PHP

    Dreamweaver CS6

    Dreamweaver CS6

    Outils de développement Web visuel

    SublimeText3 version Mac

    SublimeText3 version Mac

    Logiciel d'édition de code au niveau de Dieu (SublimeText3)

    Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

    Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

    Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

    Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

    Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

    Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

    Horodatage à ce jour en Java Horodatage à ce jour en Java Aug 30, 2024 pm 04:28 PM

    Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

    Programme Java pour trouver le volume de la capsule Programme Java pour trouver le volume de la capsule Feb 07, 2025 am 11:37 AM

    Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

    PHP vs Python: comprendre les différences PHP vs Python: comprendre les différences Apr 11, 2025 am 12:15 AM

    PHP et Python ont chacun leurs propres avantages, et le choix doit être basé sur les exigences du projet. 1.Php convient au développement Web, avec une syntaxe simple et une efficacité d'exécution élevée. 2. Python convient à la science des données et à l'apprentissage automatique, avec une syntaxe concise et des bibliothèques riches.

    PHP: un langage clé pour le développement Web PHP: un langage clé pour le développement Web Apr 13, 2025 am 12:08 AM

    PHP est un langage de script largement utilisé du côté du serveur, particulièrement adapté au développement Web. 1.Php peut intégrer HTML, traiter les demandes et réponses HTTP et prend en charge une variété de bases de données. 2.PHP est utilisé pour générer du contenu Web dynamique, des données de formulaire de traitement, des bases de données d'accès, etc., avec un support communautaire solide et des ressources open source. 3. PHP est une langue interprétée, et le processus d'exécution comprend l'analyse lexicale, l'analyse grammaticale, la compilation et l'exécution. 4.PHP peut être combiné avec MySQL pour les applications avancées telles que les systèmes d'enregistrement des utilisateurs. 5. Lors du débogage de PHP, vous pouvez utiliser des fonctions telles que error_reportting () et var_dump (). 6. Optimiser le code PHP pour utiliser les mécanismes de mise en cache, optimiser les requêtes de base de données et utiliser des fonctions intégrées. 7

    Créer l'avenir : programmation Java pour les débutants absolus Créer l'avenir : programmation Java pour les débutants absolus Oct 13, 2024 pm 01:32 PM

    Java est un langage de programmation populaire qui peut être appris aussi bien par les développeurs débutants que par les développeurs expérimentés. Ce didacticiel commence par les concepts de base et progresse vers des sujets avancés. Après avoir installé le kit de développement Java, vous pouvez vous entraîner à la programmation en créant un simple programme « Hello, World ! ». Une fois que vous avez compris le code, utilisez l'invite de commande pour compiler et exécuter le programme, et « Hello, World ! » s'affichera sur la console. L'apprentissage de Java commence votre parcours de programmation et, à mesure que votre maîtrise s'approfondit, vous pouvez créer des applications plus complexes.

    See all articles