JavaSE之Class类分析

1.前言:Class类图

在这里插入图片描述
在这里插入图片描述

2.基本介绍

在这里插入图片描述
对于理解2
class类对象是通过类加载器生成的 通过这个类加载器ClassLoder 这个类里面有个loadClass方法 这个方法完成类的加载 生成了某个类的Class对象
对于理解3 实战有 对于一个类对于类对象只有一份。就像模板一样 不会new一次就有新的类对象对于同一类来说
对于理解4 看hashcode部分
对于理解5 看右边箭头从cat对象类指向class类对象的箭头(后续有解释)
对于理解6 图中中间部分
对于理解7 图2方法区的Cat类的字节码二进制数据 类的加载完以后 除了在堆中生成一个class类对象 同时在方法区里面会得到Cat.class一个类的字节码二进制数据 这两者之间的关系为方法区的cat类字节码二进制数据引用class类对象 类对象是一种数据结构 把成员变量映射成一个对象进行操作 方法区是二进制数据 而类对象是数据结构了 更利于数据的操作 二进制数据麻烦 数据结构的操作方便
图1
图1
在这里插入图片描述

图2

3.实战

在这里插入图片描述

在这里插入图片描述
对于Cat cat=new Cat();
我们发现一上来就进入了ClassLoder这个类中了 且调用了loadClass这个方法
在这里插入图片描述
在这里插入图片描述
对于class类的forname方法依然导致了类的加载 依然到了ClassLoder的loadClass方法
也就是说
Class.forname()静态方法 1.这个class对象不是new出来的 而是系统创建出来的 2.class.forname()方法底层依然是用classloder.lodeclass()方法

实际案例

package com.ReflexReview.hspedu.Class;

//1.Classt也是类,因此也继承Object类[类图]
//2.Class类对象不是new出来的,而是系统创建的[演示]
//3.对于某个类的Class类对象,在内存中只有一份,因为类只加载一次[演示]
//4.每个类的实例都会记得自己是由哪个Class实例所生成
//5.通过Classi可以完整地得到一个类的完整结构,通过一系列AP1
//6.Class对象是存放在堆的
//7.类的字节码二进制数据,是放在方法区的,
//有的地方称为类的元数据(包括方法代码,
//变量名,方法名,访问权限等等)https:/www.zhihu.com/question/38496907【示意图】
public class Class01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //看看CLass类图
        //1.Class也足类,因此也继承Object类
        //class
        //2.Class类对象不是new出来的,而是系统创建的
        //(1)传统new对象

  /*   debug的话一上来就是 ClassLoder类
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            return loadClass(name, false);
        }*/
       // Cat cat=new Cat();
        //(2)反射方式 刚才韩老师没有debug到ClassLoder类的loadClass 原因他没有注销 Cat cat=new Cat();


        Class<?> cls1=Class.forName("com.ReflexReview.hspedu.Cat");
        // 导致之前已经加载过一次了 因为类的加载只会一次(对于同一个类 另外一个类还是要加载的)
            /*   debug的话一上来就是 ClassLoder类
              仍然是通过CLassLoder类加载Cat类的class对象
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                return loadClass(name, false);
        }*/

        //3.对于某个类的Class类对象,在内存中只有一份,因为类只加载一次[演示]
        Class cls2=Class.forName("com.ReflexReview.hspedu.Cat");
        System.out.println(cls1.hashCode());
        System.out.println(cls2.hashCode());
        Class cl3=Class.forName("com.ReflexReview.hspedu.Dog");
        //这类cl3的hashcode肯定和cls1,2的hashcode肯定不相同
        //因为是不同类 Dog和Cat类不是同一个类
        System.out.println(cl3.hashCode());
    }
}

312714112
312714112
692404036
在这里插入图片描述
在这里插入图片描述
cat和cat2对象都知道自己和哪个类对象关联
从cat对象类指向class类对象的箭头 这也就是为什么说后面可以从cat普通对象 通过一个方法可以拿到与它关联的class类对象

4.Class类的常用方法

在这里插入图片描述

  package com.ReflexReview.hspedu.Class;


import com.ReflexReview.hspedu.Car;

import java.lang.reflect.Field;

/**
 * 演示class类的常用方法
 */
public class Class02 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        String classAllPath="com.ReflexReview.hspedu.Car";
        //1.获取Car类对应的Class对象
        //<?>表示不确定的Java类型
        Class<?> cls = Class.forName(classAllPath);
        //2.输出cls
        System.out.println(cls);//显示cls对象 是哪个类的class对象 class com.ReflexReview.hspedu.Car
        System.out.println(cls.getClass());//获取cls运行类型 class java.lang.Class 这是真正运行时哪个类对象
        //3.输出包名
        System.out.println(cls.getPackage().getName()); //包名
        //4.得到全类名
        System.out.println(cls.getName());
        //5.通过cls创建对象实例
        Car car=(Car) cls.newInstance();
        System.out.println(car); //car.toString
        //6.通过反射获取属性 如果brand是私有属性会报错 这里的Field必须有class类对象
        Field brand = cls.getField("brand");
        System.out.println(brand.get(car)); //宝马
        //7.通过反射给属性赋值
        brand.set(car, "奔驰");
        System.out.println(brand.get(car));
        //8.通过获得所有属性字段
        System.out.println("===所有字段属性=====");
        Field[] fields = cls.getFields();
        for (Field f:fields
             ) {
          /*  String	getName()
            返回由此 Field对象表示的字段的名称*/
            System.out.println(f.getName());
        }
        
    }
}

class com.ReflexReview.hspedu.Car
class java.lang.Class
com.ReflexReview.hspedu
com.ReflexReview.hspedu.Car
Car{brand=‘宝马’, price=5000000, color=‘白色’}
宝马
奔驰
=所有字段属性===
brand
price
color

Process finished with exit code 0

5.获取Class类对象

在程序的不同阶段(三个阶段)可以通过不同的方法获取Class类对象
在这里插入图片描述
大体分为4种
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import com.ReflexReview.hspedu.Car;

public class GetClass {
    /*    1.前提:已知一个类的全类名,且该类在类路径下,可通过Class:类的静态方法
        forName()获取,可能抛出ClassNotFoundException,实例:Class cls1
    Class.forName("java.lang.Cat")
        应用场景:多用于配置文件,读取类全路径,加载类
            这种方式在底层框架运用贼多 很多在XML文件中写类的路径的 运用场景非常多
        */
    public static void main(String[] args) throws ClassNotFoundException {
        //1.Class.forName
        String classAllPath = "com.ReflexReview.hspedu.Car"; //通过配置文件获取
        Class<?> cls1 = Class.forName(classAllPath);
        System.out.println(cls1);
        //2.类名.class ,应用场景 :用于参数传递
        Class cls2 = Car.class;
        System.out.println(cls2);
        //3.前提:已知某个类的实例,调用该实例的getClass()方法获取Class对象
        //Class clazz=对象.getClass();//运行类型 也就是对象运行时获取Class类对象
        //也就是最右边cat对象箭头 往左指向 关联的class类对象
        //一旦创建对象 这个对象知道自己和哪个类对象关联
        //应用场景 ,有对象实例
        Car car = new Car();
        Class cls3 = car.getClass();
        System.out.println(cls3);

        //4.通过类加载器【4种】获取类的Class对象
        //(1)先通过类加载器car
         /*public final 类<?> getClass()
        返回此Object的运行时类。 返回的类对象是被表示类的static synchronized方法锁定的对象。*/
        //分步骤
        //1.getclass 通过堆Cat对象找到猫的Class类对象
        //2.getClassLoder 通过Class类对象找到类加载器
        ClassLoader classLoader = car.getClass().getClassLoader();
        //(2)通过类加载器得到Class对象
        Class cls4 = classLoader.loadClass(classAllPath);
        System.out.println(cls4);

        //cls1,cls2,cls3,cls4 其实是同一个对象
        //在我们内存里面不管你们怎么处理 在堆区只有1个对于1个Class类对象
        System.out.println(cls1.hashCode());
        System.out.println(cls2.hashCode());
        System.out.println(cls3.hashCode());
        System.out.println(cls4.hashCode());
        /*5.基本数据(int,char,boolean,float,double,byte,long,short)按如下方式得到Class类对象*/
        Class<Integer> integerClass=int.class;
        Class<Character> characterClass = char.class;
        Class<Boolean> booleanClass = boolean.class;
        System.out.println(integerClass);
        //6.基本数据类型对应的包装类,可以通过.TYPE得到Class类对象
        Class<Integer> type1 = Integer.TYPE;
        Class<Character> type2 = Character.TYPE;
        System.out.println(type1);
        System.out.println(type2);

        System.out.println(integerClass.hashCode());
        System.out.println(type1.hashCode());

true
false
312714112
312714112
692404036
int ; class java.lang.Integer
int ; java.lang.Integer

6.如下类型有 Class 对象

在这里插入图片描述

import java.io.Serializable;

public class AllTypeClass {
    public static void main(String[] args) {
        Class<String> cls1 = String.class;//外部类
        Class<Serializable> cls2 = Serializable.class;//接口
        Class<Integer[]> cls3 = Integer[].class;//数组
        Class<float[][]> cls4 = float[][].class; //二维数组
        Class<Deprecated> cls5 = Deprecated.class;//注解
        //枚举
        Class<Thread.State> cls6 = Thread.State.class;
        Class<Long> cls7 = long.class; //基本数据类型
        Class<Void> cls8 = void.class;//void数据类型
        Class<Class> cls9 = Class.class;//

        System.out.println(cls1);
        System.out.println(cls2); 
        System.out.println(cls3);
        System.out.println(cls4);
        System.out.println(cls5);
        System.out.println(cls6);
        System.out.println(cls7);
        System.out.println(cls8);
        System.out.println(cls9);
    }
}

class java.lang.String
interface java.io.Serializable
class [Ljava.lang.Integer;
class [[F
interface java.lang.Deprecated
class java.lang.Thread$State
long
void
class java.lang.Class

7.类加载

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行过程中
Dog这个类不一定用到 但是编译器不管那么多,在编译dog这个类就会加载Dog类并进行语法的校验 我们称为静态加载 编译时就会加载这个类

在这里插入图片描述
这里是动态加载 在编译时后不加载Person类 当用户运行时候选中2的时候才会加载person类 ,因此降低了程序的依赖性
这里执行结果说明编译已经通过了 反射是动态加载
在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一.类加载流程图

源代码进行编译得到字节码文件 字节码文件运行 运行时候字节码进行类加载
类加载分为了三个阶段

  1. 加载 生成ClassLoder进行加载
  2. 连接
    验证: 对文件进行安全校验(文件格式,元数据,字节码,符号引用)
    准备:对静态变量分配内存并且完成默认初始化 在方法区分配内存并默认初始化
    解析:虚拟机将常量池种的符号替换为直接引用
  3. 初始化
    初始化才会真正执行在类中去定义的Java代码 比如 静态代码块 静态变量的显式赋值显式初始化或指定初始化 功能不一样
    在这里插入图片描述
    类装载完之后 在方法区有类的字节码二进制数据元数据类里面的方法 访问权限 变量描述信息 在堆区类class对象的数据结构是数据的访问入口

最后这个初始化 是属于类加载阶段的初始化而不是类实例化的初始化 静态成员的初始化和类加载关联
在这里插入图片描述
加载和连接阶段是由JVM机控制 初始化是可以由程序员在类中书写
3.6.5 加载阶
二进制字节流加载到内存 的含义 把字节码文件加载到方法区的二进制数据/元数据同时生成这个类的Class类对象 这个Class类对象以你的二进制数据/元数据作为标准的

(1)类加载 连接阶段-验证

在这里插入图片描述
这个与SecurityManager类有关

(2)连接阶段-准备

在这里插入图片描述

package com.ReflexReview.hspedu.classload_;

public class ClassLoad02 {
    public static void main(String[] args) {

    }
}
class A{
    //属性-成员变量-字段
    //属性-成员变量-字段
    //老韩分析类加载的链接阶段-准备属性是如何处理
    //1.n1是实例属性,不是静态变量,因此在准备阶段,是不会分配内存
    //2.n2是静态变量,分配内存 n2是默认初始化0,而不是20 这里是连接-准备阶段
    //类加载最后的初始化阶段才会变成20
    //3,n3是static final是常量,他和静态变量不一样,因为一旦赋值就不变 n3=30
    public  int n1=10;
    public static int n2=20;
    public static final int n3=30;
}

(3)连接阶段-解析

编译过程中还没真正 A类和B类 还未加载到内存 或还没真正分配空间 那这个时候以符号的方式互相引用 一旦到了类加载进入内存了A类和B类Class对象 这个过程由JVM机控制 所以内存地址指定不了
在这里插入图片描述

(4)类加载最后阶段(最右边)初始化

这个阶段程序员可以开始控制执行了
这里只是与静态变量和静态代码块有关的东西和实例还没关系 这是属于类加载的过程
在这里插入图片描述在这里插入图片描述

  package com.ReflexReview.hspedu.classload_;

/**
 * 演示类加载-初始化
 */
public class ClassLoad03 {
    public static void main(String[] args) {
        //老汉分析
        //1.加载B类,并生成B的class对象
        //2.链接num=0
        //3.初始化阶段
        //依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句,并合并
       /* <clinit>(){
             System.out.println("B 静态代码块被执行");
              num=300;
              num=100
            }
            合并 num=100

       */

        System.out.println(B.num); //直接使用类B的静态属性num 也会导致类的加载
        //这时候我们看到构造器方法并没有调用
        //4.new一个对象才能执行第4步骤构造方法调用
        new B();
    }
}
class B{
    static {
        System.out.println("B 静态代码块被执行");
        num=300;
    }
    static int num=100;

    public B() {//构造器
        System.out.println("B()构造器被执行");
    }
}

B 静态代码块被执行
B()构造器被执行
100
对于理解3
3.就是表示即使在多线程情况下也能保证某个类在内存中,也只有一个Class对象

8.获取类结构信息

第一组: java.lang.Class 类

在这里插入图片描述

第二组: java.lang.reflect.Field 类

在这里插入图片描述

第三组: java.lang.reflect.Method 类

在这里插入图片描述

第四组: java.lang.reflect.Constructor 类

在这里插入图片描述

package com.ReflexReview.hspedu.classload_;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/*
        //得到Class对象
        1.getName:获取全类名
        2.getSimpleName获取简单类名
        3.getFields:获取所有publicf修饰的属性,包含本类以及父类的
        4.getDeclaredFields::获取本类中所有属性
        5.getMethods::获取所有public修饰的方法,包含本类以及父类的
        6.getDeclaredMethods:获取本类中所有方法
        7.getConstructors:获取本类所有oublicf修饰的构造器
        8.getDeclaredConstructors:获取本类中所有构造器
        9.getPackage::以Package形式返回包信息
        10.getSuperClass::以Class形式返回父类信息
        11.getInterfaces:以Class[]形式返回接口信息
        12.getAnnotations:以Annotation[]形式返回注解信息*/
/**
 * 演示如何通过反射获取类的结构信息
 */
public class ReflectionUtils {
    public static void main(String[] args) {

    }
    @Test
    public void api_02() throws ClassNotFoundException {
        //得到Class对象
        Class personCls=Class.forName("com.ReflexReview.hspedu.classload_.Person");
        //4.getDeclaredFields::获取本类中所有属性
        Field[] declaredFields= personCls.getDeclaredFields();
        /*1.getModifiers::以int形式返回修饰符
        [说明:默认修饰符是0,public是1,private是2,protected是4
        static是8,final是16],public(1)+static(8)=9
        2.getType:以Classi形式返回类型 返回这个属性对应类型举例(int sting)的class对象
        3.getName返回属性名*/
        for (Field declaredField:declaredFields
        ) {
            System.out.println("本类中所有属性"+declaredField.getName()+"该属性的修饰符值"+declaredField.getModifiers()+"该属性的类型"+declaredField.getType());
        }
      /*  1.getModifiers:以int形式返回修饰符
                [说明:默认修饰符是0,public是1,private是2,protected是4,
        static是8,final是16]
        2.getReturnType:以Class形式获取返回类型 获得这个方法的返回类型这个class类型对象
        3.getName:返▣方法名
        4.getParameterTypes:以Class[]数组返回参数类型数组*/
        //getDeclaredMethods:获取本类中所有方法
        Method[] declaredMethods = personCls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中所有方法"+declaredMethod.getName()
            +"该方法的访问修饰符"+declaredMethod.getModifiers()+"该方法的返回类型"+declaredMethod.getReturnType());
            //输出当前这个方法形参数组情况
            Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println("该方法的形参类型"+parameterType);
            }
            
        }
        //8.getDeclaredConstructors:获取本类中所有构造器
        Constructor<?>[] declaredConstructors= personCls.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("===============");
            System.out.println("本类中所有的构造器="+declaredConstructor.getName());//这里老师仅仅是输出名字
            Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println("该构造器的形参类型="+parameterType);
            }
            
        }


    }
    //第一组方法API
    @Test
    public void api_01() throws ClassNotFoundException {
        //得到Class对象 得到这个类相关的信息
        Class personCls=Class.forName("com.ReflexReview.hspedu.classload_.Person");
        // 1.getName:获取全类名
        System.out.println(personCls.getClass());
        //2.getSimpleName获取简单类名
        System.out.println(personCls.getSimpleName());
        //3.getFields:获取所有public修饰的属性,包含本类以及父类的 这里是只有public的
        Field[] fields=personCls.getFields();
        for (Field field:fields
             ) {
            System.out.println("本类和父类的属性"+field.getName());
        }
        //4.getDeclaredFields::获取本类中所有属性
        Field[] declaredFields= personCls.getDeclaredFields();
        for (Field declaredField:declaredFields
             ) {
            System.out.println("本类中所有属性"+declaredField.getName());
        }
        //5.getMethods::获取所有public修饰的方法,包含本类以及父类的 这个父类不仅仅是直接父类还有他父类的父类都可以
        Method[] methods=personCls.getMethods();
        for (Method method:methods
             ) {
            System.out.println("本类以及父类的方法"+method.getName());
        }
        //6.getDeclaredMethods:获取本类中所有方法
        Method[] declaredMethods = personCls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中所有方法"+declaredMethod.getName());
        }

        //7.getConstructors:获取本类所有oublicf修饰的构造器
        Constructor<?>[] constructors=personCls.getConstructors();
        for (Constructor<?> constructor:constructors
             ) {
            System.out.println("本类以及父类的构造器="+constructor.getName());
        }
        //8.getDeclaredConstructors:获取本类中所有构造器
        Constructor<?>[] declaredConstructors= personCls.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("本类中所有的构造器"+declaredConstructor.getName());//这里老师仅仅是输出名字
        }
        //9.getPackage::以Package形式返回包信息
        System.out.println(personCls.getPackage());
        //10.getSuperClass::以Class形式返回父类信息
        Class superclass = personCls.getSuperclass();
        System.out.println("父类的class对象="+superclass); //A
        //11.getInterfaces:以Class[]形式返回接口信息
        Class[] interfaces = personCls.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println("接口信息"+anInterface);
        }
        //12.getAnnotations:以Annotation[]形式返回注解信息
        Annotation[] annotations = personCls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("注解信息=" + annotation);

        }
        

    }
}
class A{
    public String hobby;
    public void hi(){

    }

    public A() {
    }
}
interface IA{

}
interface IB{

}
@Deprecated
class Person extends A implements IA,IB{
    //属性
    public String name;
    protected static int age; //4+8=12
    String job;
    private double sal;
    //构造器

    public Person() {
    }

    public Person(String name) {
        this.name = name;
    }

    //私有的

    private Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //方法
    public void m1(String name,int age,double sal){

    }
    protected String m2(){
        return null;
    }
    void m3(){

    }
    private void m4(){

    }
}

//第一组方法API api_01()
class java.lang.Class
Person
本类和父类的属性name
本类和父类的属性hobby
本类中所有属性name
本类中所有属性age
本类中所有属性job
本类中所有属性sal
本类以及父类的方法m1
本类以及父类的方法hi
本类以及父类的方法wait
本类以及父类的方法wait
本类以及父类的方法wait
本类以及父类的方法equals
本类以及父类的方法toString
本类以及父类的方法hashCode
本类以及父类的方法getClass
本类以及父类的方法notify
本类以及父类的方法notifyAll
本类中所有方法m1
本类中所有方法m2
本类中所有方法m4
本类中所有方法m3
本类以及父类的构造器=com.ReflexReview.hspedu.classload_.Person
本类以及父类的构造器=com.ReflexReview.hspedu.classload_.Person
本类中所有的构造器com.ReflexReview.hspedu.classload_.Person
本类中所有的构造器com.ReflexReview.hspedu.classload_.Person
本类中所有的构造器com.ReflexReview.hspedu.classload_.Person
package com.ReflexReview.hspedu.classload_
父类的class对象=class com.ReflexReview.hspedu.classload_.A
接口信息interface com.ReflexReview.hspedu.classload_.IA
接口信息interface com.ReflexReview.hspedu.classload_.IB
注解信息=@java.lang.Deprecated()

Process finished with exit code 0

第二组API
本类中所有属性name该属性的修饰符值1该属性的类型class java.lang.String
本类中所有属性age该属性的修饰符值12该属性的类型int
本类中所有属性job该属性的修饰符值0该属性的类型class java.lang.String
本类中所有属性sal该属性的修饰符值2该属性的类型double
本类中所有方法m1该方法的访问修饰符1该方法的返回类型void
该方法的形参类型class java.lang.String
该方法的形参类型int
该方法的形参类型double
本类中所有方法m2该方法的访问修饰符4该方法的返回类型class java.lang.String
本类中所有方法m4该方法的访问修饰符2该方法的返回类型void
本类中所有方法m3该方法的访问修饰符0该方法的返回类型void

本类中所有的构造器=com.ReflexReview.hspedu.classload_.Person
该构造器的形参类型=class java.lang.String
该构造器的形参类型=int

本类中所有的构造器=com.ReflexReview.hspedu.classload_.Person
该构造器的形参类型=class java.lang.String

本类中所有的构造器=com.ReflexReview.hspedu.classload_.Person

Process finished with exit code 0

9.反射爆破创建

(1)创建对象

在这里插入图片描述

package com.ReflexReview.hspedu;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * 演示通过反射机制创建实例
 */
public class ReflectCreateInstance {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //1.先获取User类的Class对象
       Class userClass= Class.forName("com.ReflexReview.hspedu.User");
        //2.通过public的无参构造器创建实例
        Object o = userClass.newInstance();
        System.out.println(o);
        //3.通过public的有参构造器创建实例
        //如果带有形参的不能通过Class对象直接new 先得到它的构造器
        //3.1必须先得到他的构造器
        Constructor constructor = userClass.getConstructor(String.class);
        //3.2然后创建实例 并传入实参
        Object hsp=constructor.newInstance("hsp");
        System.out.println("hsp"+hsp);
        //4.通过非oublic的有参构造器创建实例
        //4.1 得到private的构造器对象
        Constructor constructor1 = userClass.getDeclaredConstructor(int.class, String.class);
        //4.2
        constructor1.setAccessible(true);//暴力破解,使用反射可以访问private构造器/方法/属性 反射面前都是纸老虎
        Object user2 = constructor1.newInstance(100, "张锋");
        System.out.println("user2"+user2);

    }
}
class User{
    private int age;

    private String name="XXX教育";

    public User() { //无参 public
    }

    public User(String name) { //public有参构造器
        this.name = name;
    }

    private User(int age, String name) { //private 有参构造器
        this.age = age;
        this.name = name;
    }

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

User{age=0, name=‘XXX教育’}
hspUser{age=0, name=‘hsp’}
user2User{age=100, name=‘张锋’}

(2) 访问方法 ReflecAccessMethod.jav

在这里插入图片描述

package com.ReflexReview.hspedu;

import java.lang.reflect.Field;

/**
 * 演示反射操作属性
 */
public class ReflectAccessProperty {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //1.得到Student类对应的Class对象
        Class<?> stuClass = Class.forName("com.ReflexReview.hspedu.Student");
        //2.创建对象
        Object o = stuClass.newInstance();//o运行类型就是Student
        Student student=new Student();
        student.fuck();

        System.out.println(o.getClass()); //Student
        //3.使用反射得到age属性对象
        Field age = stuClass.getField("age");
        age.set(o,88);//通过反射操作属性

        System.out.println(o);
        System.out.println(age.get(o));//返回age的值
        //4.使用反射操作私有name属性
        Field name = stuClass.getDeclaredField("name");
        //对name进行爆破
        name.setAccessible(true);
        //name.set(o, "老韩"); //因为私有 set方法就会报错 这时候我们就得爆破
        name.set(null, "老韩");//因为name是static属性 因此o也可以写成null;
        System.out.println(o); //获取属性值
        System.out.println(name.get(o)); //获取属性值



    }
}
class Student {//类
    public int age;
    private static String name;
    public Student() {//构造器
    }
    public void fuck(){

    }
    public String toString() {
        return "Student [age=" + age + ", name=" + name + "]";
    }
}

class com.ReflexReview.hspedu.Student
Student [age=88, name=null]
88
Student [age=88, name=老韩]
老韩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值