最详细易懂的java反射

目录

一、相关基础概念

二、反射

1.反射是什么?

2反射有什么用?

3.反射怎么用?

(1)通过反射获取类的结构信息(API) 

(2)通过反射创建对象

 (3)通过反射暴破获取属性

(4)通过反射操作方法


一、相关基础概念

  1. 类对象:就是用来介绍一个类有哪些属性和方法的对象(提供类本身的信息);对反射来说类对象就是一面镜子。
  2. Class类:

(1)Class类的基本介绍

(2)Class类的相关方法

(3)Class类对象的三种获取方式

三种方式对应计算机的三个阶段(编译 加载 运行)

(4)哪些类型有类对象

(5)类的加载

静态加载和动态加载的区别,举个例子:

解释:new Dog()是静态加载,所以必须要编写Dog类,否则会报错;

        Person类是动态加载,所以,不编写Person类也不会报错,只有动态加载到该类时,才会报错;

(6)类加载的五个阶段

加载阶段就是创建一个Class类对象

连接阶段的三个子阶段

验证阶段就是验证数据的文件格式是否正确

准备阶段就是给静态变量分配内存空间

解析阶段就是当数据存储进内存时,将符号引用换成地址来引用;

初始化阶段就是通过clinit()方法自动收集静态变量和静态代码块,并合并;同时系统会保证多个线程同一时刻只有一个线程加载类(即会上锁,有同步机制控制)

重点:

1.一个类的class类对象只有一个,不管new创建多少个对象都是同一个(即哈希值相同)

2.class对象是存放在堆里面的

3.类对象有三种获取方式对应计算机的三个阶段

二、反射

1.反射是什么?

类对象就像是一面镜子,通过类对象(镜子)看到类的结构(类本身的信息,就是有哪些属性、哪些方法),这个就是反射

2反射有什么用?

  可以在不需改源代码的情况下,通过修改配置文件来控制程序(即开闭功能)

3.反射怎么用?

(1)通过反射获取类的结构信息(API) 

(2)通过反射创建对象

先拿到class类对象,再用类对象获取到构造器对象,再用构造器对象创建对象

实例代码

import java.lang.reflect.Constructor;
//韩顺平735集
//演示通过反射创对象
public class ReflectCreateInstance {
    public static void main(String[] args) throws Exception {
        //1.先获取User类的class类对象
        Class<?> user = Class.forName("getClass.User");  //注意类对象的数据类型是Class,不是User

        //2.通过public的无参构造器来创建对象
        Object u = (User) user.newInstance();//newInstance()方法是用来调用无参构造器来创建对象
        System.out.println(u);

        //3.通过public的有参构造器来创建对象
        //3.1对于有参构造器要先获取构造器对象,再用构造器对象来调用newInstance()方法(调用无参构造器来创建对象)来创建对象
        Constructor constructor = user.getConstructor(String.class);
        //3.2创建对象,并传入实参
        Object hsp =  constructor.newInstance("hsp");
        System.out.println(hsp);

        //4.通过非public的无参构造器来创建对象
        //4.1先要得到private的构造器对象
        Constructor constructor1 = user.getDeclaredConstructor(int.class, String.class);
        //4.2创建对象
        constructor1.setAccessible(true);//暴破(暴力破解),通过反射访问私有的构造器
        Object hsp1 =  constructor1.newInstance(12,"hsp");

        System.out.println(hsp1);
    }
}

class User{
    private String name = "韩顺平教育";
    private int age = 10;
    public User(){
    }
    public User(String name) {  //共有有参构造器
        this.name = name;
    }
    private User(int age,String name){  //私有有参构造器
        this.age = age;
        this.name = name;

    }

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

   (3)通过反射暴破获取属性

import java.lang.reflect.Field;
//韩顺平726集
//演示通过反射暴破获取属性
public class ReflectAccessProperty {
    public static void main(String[] args) throws Exception {
        //1.获得类对象
        Class<?> aClass = Class.forName("getClass.Student");//全类路径不要写错,包名.类名
        //2.得到类对象后,还要创建对象
        Object o = aClass.newInstance();
        //怎么获得属性
        //3.用类对象,即反射来获得age属性对象
        Field age = aClass.getField("age");
        age.set(o,88);
        System.out.println(o);

      
         //先设置还是先暴破,什么时候暴破?  暴破后才能设置
        //4.使用反射操作name属性
        Field name = aClass.getDeclaredField("name");
        name.setAccessible(true);
        name.set(o,"John");
        System.out.println(o);
    }
}

class Student{
    private String name;
    public int age;

    public Student(){

    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

(4)通过反射操作方法

import java.lang.reflect.Method;
//韩顺平727集
//演示反射操作方法
public class ReflectAccessMethod {
    public static void main(String[] args) throws Exception {
    //1.获得类对象
        Class<?> aClass = Class.forName("getClass.Boss");//全路径不要再写错了
    //2.创建对象
        Object o = aClass.newInstance();
    //3.获得方法对象
        Method hi = aClass.getDeclaredMethod("hi",String.class);//getMethod()方法根据方法名获得方法对象,并要传入方法实参
    //4.调用方法
        System.out.println( hi.invoke(o, "张三"));

    //私有方法的暴破
        Method say = aClass.getDeclaredMethod("say", int.class, String.class, char.class);
        say.setAccessible(true);
        System.out.println(say.invoke(o,100,"李四",'男'));

    }
}

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);
    }

}

类对象是为了获得对象、属性对象和方法对象(通过调用方法);

创建对象是为了设置属性和方法;

属性对象和方法对象是为了调用属性和方法;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值