java反射(暴力破解)

简介: 什么是Java反射机制?运行时动态获得类信息以及动态调取类中的成分的能力

一、名词解释

1.什么是Java反射机制?

答:运行时动态获得类信息以及动态调取类中的成分的能力

2.反射的步骤(重点):

反射的第一步都是先得到编译后的class对象,然后就可以得到class的全部成分。

二、代码实践

1.获取类的class对象

获取类的class对象有三种方式,这里只写最简单的一种方式

步骤:

Class 自定义 = 类名.class

例子:

被测试的Dog类

package learn;
public class Dog {
}

测试类

package learn;
public class Test {
    public static void main(String[] args) {
        //类名.class
        Class dog = Dog.class;//获取
        System.out.println(dog);//打印
    }
}

运行结果:

class learn.Dog

=======================================================

2.获取类的构造器对象

被测试的类(里面有有参、无参构造器、set和get方法、toSrring方法)

package learn;
public class Dog {
    private String name;
    private int age;
    //被测试类里面放有参和无参构造器和set、get方法
    public String getName() {//get
        return name;
    }
    public void setName(String name) {//set
        this.name = name;
    }
    public int getAge() {//get
        return age;
    }
    public void setAge(int age) {//set
        this.age = age;
    }
    public Dog() {
        System.out.println("无参构造器执行");
    }
    //重写toString,快捷键里面有:Alt+Insert  作用:返回打印的值
    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public Dog(String name, int age) {
        System.out.println("有参构造器执行");
        this.name = name;
        this.age = age;
    }
}

获取构造器有4种

(1)只能获取public修饰的(略)

(2)全部都可以获取(学习这个)

测试类

package learn;
import java.lang.reflect.Constructor;
public class Test {
    public static void main(String[] args) throws NoSuchMethodException {
        //1.获取类对象
        Class dog = Dog.class;
        //2.提取类对象中的全部构造器对象
        Constructor[] a = dog.getDeclaredConstructors();
        //3.用for循环遍历全部的构造器对象
        for (Constructor constructor : a) {
            //打印构造器里面的参数个数。0个代表构造器参数为0,是无参构造器        2个代表构造器有两个参数,是有参构造器
            System.out.println(constructor.getName()+"=====>"+constructor.getParameterCount());//learn.Dog=====>0     learn.Dog=====>2
        }
    }
}

运行结果:

learn.Dog=====>0

learn.Dog=====>2

(3)只能获取某个单一的public修饰的构造器(略)

(4)可以获取某个单一的构造器

测试类

package learn;
import java.lang.reflect.Constructor;
public class Test {
    public static void main(String[] args) throws Exception {
        //1,获取类对象
        Class dog = Dog.class;
        //获取单个无参构造器对象个数
        Constructor cons = dog.getDeclaredConstructor();
        System.out.println(cons.getName()+"===>"+cons.getParameterCount());
        //如果遇到了私有的构造器,进行暴力破解打开权限
        cons.setAccessible(true);
        //最后获取无参构造器对象
        Dog a  = (Dog)cons.newInstance();
        System.out.println(a);
        System.out.println("================分割线==========================");
        //获取单个有参构造器对象
        Constructor cons1= dog.getDeclaredConstructor(String.class,int.class);//被获取的成员变量是什么数据类型,这里就填什么数据类型
        System.out.println(cons1.getName()+"===>"+cons1.getParameterCount());//参数一是:获取Dog类名称,参数二:获取参数的个数
        //最后获得有构造参数
        Dog a1  = (Dog)cons1.newInstance("大哥",18);//传入赋值参数
        System.out.println(a1);
    }
}

运行结果:

learn.Dog===>0

无参构造器执行

Dog{name='null', age=0}

================分割线==========================

learn.Dog===>2

有参构造器执行

Dog{name='大哥', age=18}

=====================================================

3.获取类的成员变量

步骤:

1.获取class对象

2.获取Field对象

3.赋值或者获取值

(1)获取全部成员变量

被测试的类

package learn;
public class Dog {
    private  String name;
    private int age;
    //被测试类里面放有参和无参构造器和set、get方法
    public String getName() {//get
        return name;
    }
    public void setName(String name) {//set
        this.name = name;
    }
    public int getAge() {//get
        return age;
    }
    public void setAge(int age) {//set
        this.age = age;
    }
    public Dog() {
        System.out.println("无参构造器执行");
    }
    //重写toString,快捷键里面有:Alt+Insert  作用:返回打印的值
    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public Dog(String name, int age) {
        System.out.println("有参构造器执行");
        this.name = name;
        this.age = age;
    }
}

 测试类

package learn;
import java.lang.reflect.Field;
public class Test extends PeopleTest{
    public static void main(String[] args)  {
        //1.获取class对象
        Class dog = Dog.class;
        //2.获取全部成员变量
        Field[] fields = dog.getDeclaredFields();
        //3.用for循环遍历出来
        for (Field field : fields) {
            //4.参数一:获取具体成员变量  参数二:获取成员类型
            System.out.println(field.getName()+"====>"+field.getType());
        }
    }
}

运行结果:

name====>class java.lang.String

age====>int

(2)获取某个成员变量

被测试的类(上一个测试类)

测试类

package learn;
import java.lang.reflect.Field;
public class Test extends PeopleTest{
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        //一、获取某个成员变量
        //1.获取class对象
        Class dog = Dog.class;
        //2.获取某个成员变量---age
        Field field = dog.getDeclaredField("age");//遇到异常抛出就好
        //3.暴力打开权限
        field.setAccessible(true);
        //赋值
        Dog d = new Dog();//new要赋值的类
        field.set(d,18);//把获取到的成员变量放到新new出来的里面  赋值18
        System.out.println(d);
        //取值
        Object o = field.get(d);
        System.out.println(o);
    }
}

运行结果:

无参构造器执行

Dog{name='null', age=18}

18

=====================================================

4.获取类的方法

步骤:

1.获取类的对象

2. 用getDeclaredMethods获取全部方法或者getDeclaredMethod获取某个方法

3.用for循环遍历出来

遍历.getName()-----获取方法名字

遍历.getReturnType()--获取方法返回值的类型

遍历.getParameterCount()--获取方法个数

如果获取某个就不用遍历和需要暴力破解,在第二步时候不一样,其他的基本一样

(1)获取全部方法

被测试的类

package learn;
public class Dog {
    //自定义的成员变量
    private  String name;
    public int age;
    //生成的有参构造
    public Dog(String name) {
        this.name = name;
    }
    //狗跑的方法
    public void run(){
        System.out.println("狗在跑");
    }
    //狗在吃东西的方法
    public String eat(){
        System.out.println("我会吃");
        return "吃的很开心";
    }
//生成的set和get方法
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

测试类

package learn;
import java.lang.reflect.Method;
public class Test extends PeopleTest{
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        //1.获取类的对象
        Class c = Dog.class;
        //2.获取全部方法(包括私有)---用getDeclaredMethods方法获取
        Method[] methods = c.getDeclaredMethods();
        //遍历全部方法
        for (Method method : methods) {
            System.out.println(method.getName()+"这是方法的名字"+method.getReturnType()+"这是返回值类型"+method.getParameterCount()+"参数个数");
        }
    }
}

运行结果:

getName这是方法的名字class java.lang.String这是返回值类型0参数个数

run这是方法的名字void这是返回值类型0参数个数

setName这是方法的名字void这是返回值类型1参数个数

eat这是方法的名字class java.lang.String这是返回值类型0参数个数

(1)获取某个方法

被测试的类(上一个测试类)

测试类

package learn;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test extends PeopleTest{
    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        //1.获取类的对象
        Class c = Dog.class;
        //2.获取某个方法
        Method m = c.getDeclaredMethod("run");//获取run方法,遇到异常直接抛出
        //暴力打开权限
        m.setAccessible(true);
        //3.触发方法的执行
        Dog d = new Dog();
        //注意:如果没有方法返回来的,那么就会返回null
        Object invoke = m.invoke(d);
        System.out.println(invoke);
    }
}

运行结果:

狗在跑

null

旁白:反射就是先通过获取类的对象,然后再根据需要看获取构造方法、成员变量或者方法,根据需要获取,一般全部获得用得都是数组方式,用到的方法里面会含有一个s。而用到暴力打开私有权限的最多的就是获取单一某个成员变量时候了。反射还有一个擦除泛型的,就是破坏泛型原则的,目前这篇文章里面主要讲的就是破坏封装性的。  

目录
相关文章
|
2月前
|
存储 Java
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
22 0
[Java]反射
|
3月前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
67 9
Java——反射&枚举
|
2月前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
26 2
|
3月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
2月前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
17 0
|
3月前
|
Java 程序员 编译器
Java的反射技术reflect
Java的反射技术允许程序在运行时动态加载和操作类,基于字节码文件构建中间语言代码,进而生成机器码在JVM上执行,实现了“一次编译,到处运行”。此技术虽需更多运行时间,但广泛应用于Spring框架的持续集成、动态配置及三大特性(IOC、DI、AOP)中,支持企业级应用的迭代升级和灵活配置管理,适用于集群部署与数据同步场景。
|
3月前
|
存储 安全 Java
扫盲java基础-反射(一)
扫盲java基础-反射(一)
|
3月前
|
Java
扫盲java基础-反射(二)
扫盲java基础-反射(二)
|
5月前
|
安全 Java 测试技术
day26:Java零基础 - 反射
【7月更文挑战第26天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
35 5
|
4月前
|
缓存 安全 Java
【Java 第十篇章】反射
Java 反射技术让程序能在运行时动态获取类信息并操作对象,极大提升了灵活性与扩展性。本文将介绍反射的基本概念、原理及应用,包括如何使用 `Class`、`Field`、`Method` 和 `Constructor` 类进行动态操作。此外,还将探讨反射在动态加载、框架开发与代码测试中的应用场景,并提醒开发者注意性能与安全方面的问题,帮助你更合理地运用这一强大工具。
33 0