Java安全-2.反射机制

Java 反射机制

Java反射机制是在运行时动态地获取类的信息以及调用类的方法和操作类的属性的能力。程序中的对象在编译时只确定下来类型,反射机制允许程序在运行时获取类的信息,如类名、方法、字段、构造函数等,这使得程序可以在运行时动态地加载、探索和使用类,不需要提前在编译时就知道运行的对象是谁,从而增强了程序的灵活性和扩展性。

因此通过反射,对象可以动态地获取类,类可以通过反射拿到所有的方法,包括私有方法,并且可以直接进行调用。使得Java静态语言有了类似于PHP的动态特性(eg:一句话木马)

反射机制常用的类文件

  1. Java.lang.Class:Java反射机制的核心,Class类代表了Java中的类和接口,可通过该类所提供的方法获取有关类的信息,实现动态加载,创建类的实力,调用

  2. Java.lang.reflect.Constructor;:表示类的构造函数。可以获取构造函数的信息并实例化对象
  3. Java.lang.reflect.Field;: 表示类的字段(成员变量),可以获取字段的信息并操作类的属性
  4. Java.lang.reflect.Method;: 表示类的方法,可以获取方法的信息并嗲用类的方法。
  5. Java.lang.reflect.Modifier;:是反射机制中的一个工具类,用于解析类,字段,方法等的修饰符。

获取Class对象

通常共三种方式:

  1. 类名.class:e.g.:Parar.class;(静态方法),如果上下文存在每个实例的对象,且只想获得java.lang.Class对象时,可以直接通过此方法获得它的类
  2. obj.getClass:如果上下文存在每个实例的对象,可以直接通过此方法获得它的类
  3. Class.forName():e.g.:Class.forName("Parar"); (不属于反射)知道某个类的名字就可以直接通过此方法获取(后台直接进行加载)

示例:

首先创造一个类:Parar.java

public class Parar {
    private int age;
    private String name;
    public Parar(){
        this.age=19;
        this.name="Parar";
    }
    public void selfIntroduction(){
         System.out.println("My name is"+name+" and "+age+" years pld.");
    }
}
  1. 通过类名.class获取:

Main.java

javapublic class Main {
    public static void main(String[] args){
        System.out.println(Parar.class);
    }
}

image-20240320131208807

  1. 通过类名.getClass方法获取
public class Main {
    public static void main(String[] args){
        Parar parar = new Parar();
        Class<?> clazz = parar.getClass(); //泛型,表示一个未知类型的类,进行通配
        System.out.println(clazz);
    }
}

image-20240320131902826

  1. 通过Class.forName()

    public class Main {
       public static void main(String[] args)throws  Exception{
           Class<?> clazz =Class.forName("Parar");
           System.out.println(clazz);
       }
    }

image-20240320132529513

通过反射实例化对象

获得了了Class对象之后,下一步就是将获得的对象进行实例化

  1. 通过Class的newInstance方法

    public class Main {
       public static void main(String[] args)throws  Exception{
           Class<?> clazz =Class.forName("Parar");
           Object obj = clazz.newInstance();
           System.out.println(obj.toString());
       }
    }

    image-20240320202721423

  2. 通过Constructor的newInstance()方法

    import java.lang.reflect.*;
    public class Main {
       public static void main(String[] args)throws  Exception{
           Class<?> clazz =Class.forName("Parar");
           Constructor<?> con = clazz.getConstructor();
           Object obj = con.newInstance();
           System.out.println(obj);
       }
    }

    image-20240320204214327

操作属性

根据前两步,已经获得了类并成功将类进行了实例化

通过Class对象的getFields()(返回数组)或者getField()方法可以获得该类所包括的全部Field属性或指定Field属性。

FIled类提供了几种方法进行操作属性

  1. Field.getName()获取属性名
  2. Field.getModifiers()获取属性的修饰列表
  3. Field.getType()返回属性类型
  4. Field.set("obj","value")对属性进行赋值操作,但无法访问私有属性
  5. Field.get("obg")获取属性值
  6. Field.setAccessible(true or false);打破封装,可以进行set操作

代码示例:

import java.lang.reflect.*;
public class Main {
    public static void main(String[] args)throws  Exception{
        Class<?> clazz =Class.forName("Parar");
        Constructor<?> con = clazz.getConstructor();
        Object obj = con.newInstance();
        //获取属性名
        Field field = clazz.getField("name");
        String name = field.getName();
        System.out.println("getName():"+name);
        //获取属性的修饰符列表
        int Modifiers = field.getModifiers();
        System.out.println("Modifiers():"+Modifiers);
        //获取属性类型
        Class<?> type=field.getType();
        System.out.println("getType():"+type);
        //获取属性值
        Object oldValue = field.get(obj);
        System.out.println("old:field.get()::"+oldValue);
        //对对象进行赋值
        field.set(obj,"parar");
        Object newValue=field.get(obj);
        System.out.println("new:field.get()::"+newValue);
    }
}

image-20240320213032669

执行方法

  • 通过Class对象的getMethods() 方法可以获得该类所包括的全部方法, 返回值是Method[]
  • 通过Class对象的getMethod()方法可以获得该类所包括的指定方法, 返回值是Method
  • 每个Method对象对应一个方法,获得Method对象后,可以调用其invoke("") 来调用对应方法
  • Object invoke(Object obj,Object [] args):obj代表当前方法所属的对象的名字,args代表当前方法的参数列表,返回值Object是当前方法的返回值,即执行当前方法的结果。(当调用静态方法static时,obj为null)

e.g.:

import java.lang.reflect.*;
public class Main {
    public static void main(String[] args)throws  Exception{
        Class<?> clazz =Class.forName("Parar");
        Constructor<?> con = clazz.getConstructor();
        Object obj = con.newInstance();
        Method method= clazz.getDeclaredMethod("selfIntroduction");
        System.out.println("getDeclaredMethod:"+method);
        String name = method.getName();
        System.out.println("method.getName():"+name);
        int Modifiers1=method.getModifiers();
        System.out.println("getModifiers: "+Modifier.toString(Modifiers1));
        Class<?> returnType = method.getReturnType();
        Class<?>[] parameterTypes=method.getParameterTypes();
        method.invoke(obj);
    }
}

image-20240320220352636

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇