反射知识点学习

news2024/11/29 1:56:51

文章目录

    • 1. Java 反射机制原理示意图
      • 1.1 反射相关的主要类
      • 1.2 反射的优点和缺点
      • 1.3 反射调用优化-关闭访问检查
    • 2. Class 类
      • 2.1 基本介绍
      • 2.2 Class类的常用方法
      • 2.3 获取 Class 类对象
    • 3. 哪些类型有 Class 对象
    • 4. 类加载
      • 4.1 基本说明
      • 4.2 类加载时机
      • 4.3 类加载过程图
      • 4.4 类加载各阶段完成任务
      • 4.5 加载阶段
      • 4.6 连接阶段-验证
      • 4.7 连接阶段-准备
      • 5. 连接阶段-解析
      • 6. Initialization(初始化)
    • 5. 通过反射获取类的结构信息
      • 5.1 第一组:java.lang.Class 类
      • 5.2 第二组:java.lang.reflect.Field 类
      • 5.3 第三组: java.lang.reflect.Method 类
      • 5.4 第四组:java.lang.reflect.Constructor 类
    • 6. 通过反射创建对象
    • 7. 通过反射访问类中的成员
      • 7.1 访问属性 ReflecAccessProperty.java
      • 7.2 访问方法 ReflecAccessMethod.java
    • 8. 本章作业

image-20230928163222663

1. Java 反射机制原理示意图

image-20230928163240928

  • Java反射机制可以完成

image-20230928163343071

1.1 反射相关的主要类

image-20230928163416900

package com.xjz.reflection;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class Reflection01 {
    public static void main(String[] args) throws Exception {

        //1. 使用 Properties 类,可以读写配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\re.properties"));
        String classfullpath = properties.get("classfullpath").toString(); // "com.xjz.Cat"
        String methodName = properties.get("method").toString(); //"hi"

        //2. 使用反射机制解决
        //(1) 加载类,返回 Class 类型的对象 cls
        Class cls = Class.forName(classfullpath);
        //(2) 通过 cls 得到你加载的类 com.xjz.Cat 的对象实例
        Object o = cls.newInstance();
        System.out.println("o 的运行类型=" + o.getClass());//运行类型
        //(3) 通过 cls 得到你加载的类 com.xjz.Cat 的 methodName “hi” 的方法对象
        //    即:在反射中,可以把方法视为对象(万物皆对象)
        Method method = cls.getMethod(methodName);
        //(4) 通过 method 调用方法:即通过方法对象类实现调用方法
        System.out.println("=======================");
        method.invoke(o); //传统对象 对象.方法(),反射机制 方法.invoke(对象)
        //java.lang.reflect.Field: 代表类的成员变量, Field 对象表示某个类的成员变量
        //得到 name 字段
        //getField 不能得到私有的属性
        Field ageField = cls.getField("age");
        System.out.println(ageField.get(o));//传统写法 对象.成员变量 , 反射:成员变量对象.get(对象)

        //java.lang.reflect.Constructor: 代表类的构造方法, Constructor 对象表示构造器
        Constructor constructor = cls.getConstructor();//()中可以指定构造器参数类型,返回无参构造器
        System.out.println(constructor);//public com.xjz.Cat()

        Constructor constructor2 = cls.getConstructor(String.class);//这里传入的 String.class 就是 String类的 Class对象
        System.out.println(constructor2); //public com.xjz.Cat(java.lang.String)

    }
}

1.2 反射的优点和缺点

image-20230928170555665

1.3 反射调用优化-关闭访问检查

image-20230928171454966

image-20230928171547125

package com.xjz.reflection;

import com.xjz.Cat;

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

/**
 * @author xjz_2002
 * @version 1.0
 * 测试反射调用的性能,和优化方案
 */
public class Reflection02 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

//        Field
//        Method
//        Constructor
        //上面三个类都继承了 AccessibleObject类
        m1(); //传统  0ms
        m2(); //反射  1750ms
        m3(); //反射优化    1268ms


    }

    //传统方法来调用 hi
    public static void m1() {
        Cat cat = new Cat();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            cat.hi();
        }
        long end = System.currentTimeMillis();
        System.out.println("m1() 耗时=" + (end - start));
    }

    //反射机制调用方法 hi
    public static void m2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("com.xjz.Cat");
        Object o = cls.newInstance(); //实例化反射对象
        Method hi = cls.getMethod("hi");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);//反之调用方法
        }
        long end = System.currentTimeMillis();
        System.out.println("m2() 耗时=" + (end - start));
    }

    //反射调用优化 + 关闭访问检查
    public static void m3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class cls = Class.forName("com.xjz.Cat");
        Object o = cls.newInstance(); //实例化反射对象
        Method hi = cls.getMethod("hi");
        hi.setAccessible(true);//在反射调用方法时,取消访问检查,提高性能
        long start = System.currentTimeMillis();
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);//反之调用方法
        }
        long end = System.currentTimeMillis();
        System.out.println("m3() 耗时=" + (end - start));
    }
}

2. Class 类

2.1 基本介绍

image-20230928172213503

image-20230928172250021

package com.xjz.reflection.class_;

import com.xjz.Cat;

/**
 * @author xjz_2002
 * @version 1.0
 * 对 Class 类特点的梳理
 */
public class Class01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //看看 Class 类图
        //1. Class 也是类,因此也继承 Object 类
//        Class
        //2. Class类对象不是 new 出来的,而是系统创建的
        //(1) 传统 new 对象
        /* ClassLoader 类
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                return loadClass(name, false);
            }
         */
        //Cat cat = new Cat();
        //(2) 反射方式,刚才没有 debug 到 ClassLoader 类的loadClass,
        // 原因是 没有注销Cat cat = new Cat(); 即: 类只加载一次
        /*
            ClassLoader 类, 仍然是通过 ClassLoader 类加载 Cat 类的 Class 对象
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                return loadClass(name, false);
            }
            */
        Class<?> cls1 = Class.forName("com.xjz.Cat");

        //3. 对于某个类的 Class类对象,在内存中只有一份,因为类只加载一次
        Class<?> cls2 = Class.forName("com.xjz.Cat");
        System.out.println(cls1.hashCode());//356573597
        System.out.println(cls2.hashCode());//356573597
        Class<?> cls3 = Class.forName("com.xjz.Dog");
        System.out.println(cls3.hashCode());//1735600054
    }
}

2.2 Class类的常用方法

image-20230928174347986

package com.xjz.reflection.class_;

import com.xjz.Car;

import java.lang.reflect.Field;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示 Class 类的常用方法
 */
public class Class02 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {

        String classAllPath = "com.xjz.Car";
        //1. 获取到 Car 类对应的 Class 对象
        //<?> 表示不确定的 Java 类型
        Class cls = Class.forName(classAllPath);
        //2. 输出 cls
        System.out.println(cls);//显示 cls 对象,是哪个类的 Class 对象 即:class com.xjz.Car
        //3. 得到报名
        System.out.println(cls.getPackage().getName());//包名 com.xjz
        //4. 得到全类名
        System.out.println(cls.getName());//com.xjz.Car
        //5. 通过 cls 创建对象实例
        Car car = (Car) cls.newInstance();
        System.out.println(car); //car.toString()
        //6. 通过反射获取属性 brand
        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) {
            System.out.println(f.getName()); //名称
        }

    }
}

2.3 获取 Class 类对象

image-20230928180145691

image-20230928180151255

image-20230928180157283

package com.xjz.reflection.class_;

import com.xjz.Car;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示得到 Class 对象的各种方式(6)
 */
public class GetClass_ {
    public static void main(String[] args) throws ClassNotFoundException {

        //1. Class.forName
        String classAllPath = "com.xjz.Car";//通过读取配置文件获取
        Class<?> cls1 = Class.forName(classAllPath);
        System.out.println(cls1);

        //2. 类名.class,应用场景:用于参数传递
        Class cls2 = Car.class;
        System.out.println(cls2);

        //3. 对象.getClass(),应用场景:有对象实例
        Car car = new Car();
        Class cls3 = car.getClass();
        System.out.println(cls3);

        //4. 通过类加载器【4种】来获取到类的 Class 对象
        //(1) 先得到类加载器 car
        ClassLoader classLoader = car.getClass().getClassLoader();
        //(2) 通过类加载器得到 Class 对象
        Class cls4 = classLoader.loadClass(classAllPath);
        System.out.println(cls4);

        //cls1 , cls2 , cls3 , cls4 其实是同一个对象
        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,short,long) 按如下方式得到 Class 类对象
        Class<Integer> integerClass = int.class;
        Class<Character> characterClass = char.class;
        Class<Boolean> booleanClass = boolean.class;
        System.out.println(integerClass);//int

        //6. 基本数据类型对应的包装类,可以通过 .TYPE 得到 Class 类对象
        Class<Integer> type1 = Integer.TYPE;
        Class<Character> type2 = Character.TYPE;//其它包装类 BOOLEAN, DOUBLE, LONG,BYTE 等等
        System.out.println(type1);

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

    }
}

3. 哪些类型有 Class 对象

image-20230928184711589

package com.xjz.reflection.class_;

import com.sun.org.apache.bcel.internal.classfile.Deprecated;

import java.io.Serializable;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示哪些类型有 Class 对象
 */
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);
    }
}

4. 类加载

4.1 基本说明

image-20230928192003731

4.2 类加载时机

image-20230928192053660

4.3 类加载过程图

image-20230928192110265

4.4 类加载各阶段完成任务

image-20230928192132922

4.5 加载阶段

image-20230928192155241

4.6 连接阶段-验证

image-20230928192223356

4.7 连接阶段-准备

image-20230928192237893

package com.xjz.reflection.classLoad_;

/**
 * @author xjz_2002
 * @version 1.0
 * 我们说明一个类加载的链接阶段-准备
 */
public class ClassLoad02 {
    public static void main(String[] args) {
        
    }
}
class A {
    //属性-成员变量-字段
    //分析类加载的链接阶段-准备 属性是如何处理
    //1. n1 是实例属性,不是静态变量,因此在准备阶段,是不会分配内存
    //2. n2 是静态变量,分配内存 n2 是默认初始化 0,而不是 20
    //3. n3 是 static final 是常量,他和静态变量不一样,因为一旦赋值就不变 n3 = 30
    public int n1 = 10;
    public static int n2 = 20;
    public static final int n3 = 30;
}

5. 连接阶段-解析

image-20230928192623999

6. Initialization(初始化)

image-20230928192644741

package com.xjz.reflection.classLoad_;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示类加载-初始化阶段
 */
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
        */

        //new B();//类加载
        //System.out.println(B.num);//100, 如果直接使用类的静态属性,也会导致类的加载
        //看看加载类的时候,是有同步机制控制
        /*
        protected Class<?> loadClass(String name, boolean resolve)
        throws ClassNotFoundException
        {
            //正因为有这个机制,才能保证某个类在内存中, 只有一份 Class 对象
            synchronized (getClassLoadingLock(name)) {
            //.... }
        }
        */
        B b = new B();
    }
}
class B {
    static {
        System.out.println("B 静态代码块执行");
        num = 300;
    }

    static int num = 100;

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

5. 通过反射获取类的结构信息

5.1 第一组:java.lang.Class 类

image-20230930151133200

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

image-20230930151234712

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

image-20230930151326302

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

image-20230930151502568

package com.xjz.reflection;

import org.junit.jupiter.api.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示如何通过反射获取类的结构信息
 */
public class ReflectionUtils {
    public static void main(String[] args) {

    }

    @Test
    public void api_02() throws ClassNotFoundException {

        //得到 Class对象
        Class<?> personCls = Class.forName("com.xjz.reflection.Person");
        // getDeclaredFields: 获取本类中所有的属性
        //规定 说明: 默认修饰符 是 0 , public 是 1 ,private 是 2 ,protected 是 4 , static 是 8 ,final 是 16
        Field[] declaredFields = personCls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类中所有的属性=" + declaredField.getName()
                            + " 该属性的修饰符值=" + declaredField.getModifiers()
                            + " 该属性的类型=" + declaredField.getType());
        }

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

        //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.xjz.reflection.Person");
        // getName 获取全类名
        System.out.println(personCls.getName());//com.xjz.reflection.Person
        // getSimpleName:获取简单类名
        System.out.println(personCls.getSimpleName());//Person
        // getFields: 获取所有 public 修饰的属性,包含本类以及父类的
        Field[] fields = personCls.getFields();
        for (Field field : fields) { //增强for
            System.out.println("本类以及父类的属性=" + field.getName()); //name , hobby
        }
        // getDeclaredFields: 获取本类中所有的属性
        Field[] declaredFields = personCls.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类中所有的属性=" + declaredField.getName());
        }
        // getMethods: 获取所有 public 修饰的方法,包含本类以及父类的
        Method[] methods = personCls.getMethods();
        for (Method method : methods) {
            System.out.println("本类以及父类的方法=" + method.getName());
        }
        //getDeclaredMethods:获取本类中所有方法
        Method[] declaredMethods = personCls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类中所有方法=" + declaredMethod.getName());
        }
        //getConstructors: 获取所有 public 修饰的构造器,包含本类
        Constructor<?>[] constructors = personCls.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("本类的构造器=" + constructor.getName());
        }
        //getDeclaredConstructors:获取本类中所有构造器
        Constructor<?>[] declaredConstructors = personCls.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("本类中所有构造器=" + declaredConstructor.getName());//这里我们只输出名字
        }
        //getPackage:以 Package 形式返回 包信息
        System.out.println(personCls.getPackage());//com.hspedu.reflection
        //getSuperClass:以 Class 形式返回父类信息
        Class<?> superclass = personCls.getSuperclass();
        System.out.println("父类的 class对象=" + superclass);
        //getInterfaces:以 Class[]形式返回接口信息
        Class<?>[] interfaces = personCls.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println("接口信息=" + anInterface);
        }
        //getAnnotations:以 Annotation[] 形式返回注解信息
        Annotation[] annotations = personCls.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("注解信息=" + annotation);//注解
        }

    }


}
class A {
    public String hobby;

    public void hi(){

    }

    public A(){}

    public A(String name){

    }
}
interface IA{
}
interface IB{

}

@Deprecated
class Person extends A implements IA,IB{
    //属性
    public String name;
    protected static int age;
    String job;
    private double sal;

    //构造器
    public Person(){

    }
    public Person(String name){

    }

    //私有的
    public Person(String name,int age){

    }

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

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

    }
    private void  m4(){

    }
}

6. 通过反射创建对象

image-20230930151549506

  • 测试 1:通过反射创建某类的对象,要求该类中必须有 public 的无参构造
  • 测试 2:通过调用某个特定构造器的方式,实现创建某类的对象
package com.xjz.reflection;

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

/**
 * @author xjz_2002
 * @version 1.0
 * 演示通过反射机制创建实例
 */
public class ReflecCreateInstance {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        //1. 先获取 User 类的 Class 对象
        Class<?> userClass = Class.forName("com.xjz.reflection.User");
        //2. 通过 public的无参构造器创建实例
        Object o = userClass.newInstance();
        System.out.println(o);
        //3. 通过 public 的有参构造器创建实例
        /*
            constructor 对象就是
            public User(String name) {//public 的有参构造器
                this.name = name;
            }
         */
        //3.1 先得到对应构造器
        Constructor<?> constructor = userClass.getConstructor(String.class);
        //3.2 创建实例,并传入实参
        Object xjz = constructor.newInstance("xjz");
        System.out.println("xjz=" + xjz);
        //4. 通过非 public 的有参构造器创建实例
        //4.1 得到 private 的构造器对象
        Constructor<?> constructor2 = userClass.getDeclaredConstructor(int.class, String.class);
        //4.2 创建实例
        //暴破【暴力破解】,使用反射可以访问 private 构造器/方法/属性,反射面前,都是纸老虎
        constructor2.setAccessible(true);
        Object user2 = constructor2.newInstance(100, "张杰");
        System.out.println("user2=" + user2);


    }
}

class User { // User 类
    private int age = 10;
    private String name = "xjz_2002";

    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 + ']';
    }
}

7. 通过反射访问类中的成员

7.1 访问属性 ReflecAccessProperty.java

image-20230930151705599

package com.xjz.reflection;

import java.lang.reflect.Field;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示反射操作属性
 */
public class ReflecAccessProperty {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {

        //1. 得到 Student 类对应的 Class 对象
        Class<?> stuClass = Class.forName("com.xjz.reflection.Student");
        //2. 创建对象
        Object o = stuClass.newInstance();// o 的运行类型是 Student
        System.out.println(o.getClass());//Student
        //3. 使用反射得到 age 属性对象
        Field age = stuClass.getField("age");
        age.set(o,21);//通过反射来操作属性
        System.out.println(o);
        System.out.println(age.get(o));//返回 age属性的值

        //4. 使用反射操作 name 属性
        Field name = stuClass.getDeclaredField("name");
        //对 name 进行暴破,可以操作 private 属性
        name.setAccessible(true);
//        name.set(o,"老徐");
        name.set(null,"老徐"); //因为 name 是 static 属性,因此 o 也可以写出 null
        System.out.println(o);
        System.out.println(name.get(o));//获取属性值
        System.out.println(name.get(null));//获取属性值,要求 name 是 static


    }
}

class Student { //类
    public int age;
    private static String name;

    public Student() { //构造器
    }

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

7.2 访问方法 ReflecAccessMethod.java

image-20230930151820601

package com.xjz.reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author xjz_2002
 * @version 1.0
 * 演示通过反射调用方法
 */
public class ReflecAccessMethod {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        //1. 得到 Boos 类对应的 Class 对象
        Class<?> bossCls = Class.forName("com.xjz.reflection.Boss");
        //2. 创建对象
        Object o = bossCls.newInstance();
        //3. 调用 public 的 hi 方法
        //Method hi = bossCls.getMethod("hi", String.class);
        //3.1 得到 hi 方法对象
        Method hi = bossCls.getDeclaredMethod("hi", String.class);
        //3.2 调用
        hi.invoke(o,"张国荣");

        //4. 调用 private static 方法
        //4.1 得到 say 方法对象
        Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class);
        //4.2 因为 say 方法是 private,所有需要暴破,原理和前面的构造器和属性一样
        say.setAccessible(true);
        System.out.println(say.invoke(o,21,"xjz",'男'));
        //4.3 因为 say 方法是 static的,还可以这样调用,可以传入 null
        System.out.println(say.invoke(null,22,"tom",'女'));

        //5. 在反射中,如果方法有返回值,统一返回 Object,但是他运行类型和方法定义的返回类型一致
        Object reVal = say.invoke(null, 300, "王五", '男');
        System.out.println("reVal 的运行类型=" + reVal.getClass());//String

        //再演示一个返回的案例
        Method m1 = bossCls.getDeclaredMethod("m1");
        Object reVal2 = m1.invoke(o);
        System.out.println("reVal2 =运行类型=" + reVal2.getClass()); //Monster


    }
}

class Monster {
}

class Boss {//类
    public int age;
    private static String name;

    public Boss() {//构造器
    }

    public Monster m1() {
        return new Monster();
    }

    private static String say(int n, String s, char c) {//静态方法
        return n + " " + s + " " + c;
    }

    public void hi(String s) {//普通 public 方法
        System.out.println("hi " + s);
    }
}

8. 本章作业

image-20230930151849221

package com.xjz.homework;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class Homework01 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        //1. 得到 PrivateTest类对应的 Class对象
        Class<PrivateTest> privateTestClass = PrivateTest.class;
        //2. 创建对象实例
        PrivateTest privateTestObj = privateTestClass.newInstance();
        //3. 得到 name 属性对象
        Field name = privateTestClass.getDeclaredField("name");
        //4. 暴破name
        name.setAccessible(true);
        name.set(privateTestObj,"xjz");
        //5. 得到getName方法对象
        Method getName = privateTestClass.getMethod("getName");
        //6. 因为getName() 是public,所有直接嗲用
        Object invoke = getName.invoke(privateTestObj);
        System.out.println("name属性值=" + invoke);
    }
}

class PrivateTest {
    private String name = "hellokitty";
    //默认无参构造器
    public String getName(){
        return name;
    }
}

image-20230930151918622

package com.xjz.homework;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author xjz_2002
 * @version 1.0
 */
public class Homework02 {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {

        //1. Class类的forName方法得到File类的 class对象
        Class<?> fileClass = Class.forName("java.io.File");
        //2. 得到所有的构造器
        Constructor<?>[] declaredConstructors = fileClass.getDeclaredConstructors();
        //遍历输出
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("File的类所有构造器=" + declaredConstructor);
        }
        //3. 指定得到 public java.io.File(java.lang.String)
        Constructor<?> constructor = fileClass.getConstructor(String.class);
        String fileAllPath = "d:\\mynew.txt";
        Object file = constructor.newInstance(fileAllPath); //创建File对象

        //4. 得到createNewFile 方法对象
        Method createNewFile = fileClass.getMethod("createNewFile");
        createNewFile.invoke(file);//创建文件,调用的是 createNewFile
        //file 的运行类型就是File
        System.out.println(file.getClass());//class java.io.File
        System.out.println("创建文件成功" + fileAllPath);

    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1052293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国庆作业1

使用消息队列实现进程之间的通信 代码 write.c #include <myhead.h> //消息结构体 typedef struct {long msgtype; //消息类型char data[1024]; //消息正文 }Msg_ds;#define SIZE sizeof(Msg_ds)-sizeof(long) //正文大小 int main(int argc, cons…

算法-位运算-只出现一次的数字 II

算法-位运算-只出现一次的数字 II 1 题目概述 1.1 题目出处 https://leetcode.cn/problems/bitwise-and-of-numbers-range/description/?envTypestudy-plan-v2&envIdtop-interview-150 1.2 题目描述 2 逐个按位与运算 2.1 思路 最简单的就是直接挨个做与运算&#x…

transformers简介

目录 1、前言 2、网络结构 &#xff08;1&#xff09;、Transformers的总体架构可以分为四部分 &#xff08;2&#xff09;、输入文本包含 &#xff08;3&#xff09;、输出部分包含 &#xff08;4&#xff09;、编码器部分 &#xff08;5&#xff09;、解码器部分 1、前…

dbeaver连接国产数据库

dbeaver是常用的数据库连接工具。但是在连接一些国产的数据库时&#xff0c;因为没有可选的驱动&#xff0c;所以需要我们先设置驱动&#xff0c;在连接。以下是一个连接highgo例子。 首先先新增一个驱动&#xff1a; 在页面的菜单栏&#xff0c;选择 数据库 ->驱动管理器…

SpringBoot整合阿里云OSS文件存储解决方案

&#x1f9d1;‍&#x1f4bb;作者名称&#xff1a;DaenCode &#x1f3a4;作者简介&#xff1a;啥技术都喜欢捣鼓捣鼓&#xff0c;喜欢分享技术、经验、生活。 &#x1f60e;人生感悟&#xff1a;尝尽人生百味&#xff0c;方知世间冷暖。 &#x1f4d6;所属专栏&#xff1a;Sp…

【AI视野·今日Sound 声学论文速览 第十五期】Fri, 29 Sep 2023

AI视野今日CS.Sound 声学论文速览 Fri, 29 Sep 2023 Totally 1 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Audio-Visual Speaker Verification via Joint Cross-Attention Authors R. Gnana Praveen, Jahangir Alam使用语音信号进行了说话人验证的…

Web开发-新建Spring Boot项目

目录 Spring Boot 与 Web开发Spring Boot 与 MavenJava 环境搭建下载JDK下载xmapp下载navicat for mysql下载Eclipse配置tomcat配置maven 新建Spring Boot项目 Spring Boot 与 Web开发 Spring Boot 是一种用于简化 Spring 应用程序开发、部署和运行的框架&#xff0c;而 Web 开…

【LeetCode】滑动窗口妙解无重复字符的最长子串

Problem: 3. 无重复字符的最长子串 文章目录 思路算法原理分析暴力枚举 哈希表滑动窗口 复杂度Code 思路 首先我们来分析一下本题的思路 如果读者有看过 长度最小的子数组 的话就可以清楚这个子串其实和子数组是一个道理&#xff0c;都是 连续的一段区间但是呢它们本质上还是存…

【数据结构】队列和栈

大家中秋节快乐&#xff0c;玩了好几天没有学习&#xff0c;今天分享的是栈以及队列的相关知识&#xff0c;以及栈和队列相关的面试题 1.栈 1.1栈的概念及结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作…

Java字符缓冲流自己特有的方法进行读入和写出

代码如下&#xff1a; public class MyWork {public static void main(String[] args) throws IOException{BufferedReader fr new BufferedReader(new FileReader("myfile/abc.txt"));BufferedWriter fw new BufferedWriter(new FileWriter("myfile/test.tx…

(一)gitblit安装教程

(一)gitblit安装教程 (二) gitblit用户使用教程 (三) gitblit管理员手册 目录 前言安装1.下载Java Runtime Requirement 2.设置环境变量3.gitblit内容3.1 gitblit文件夹内容3.2 defaults.properties 主要配置选项 4 配置4.1 准备文件4.2 修改gitblit.properties4.3 修改authori…

第十四届蓝桥杯大赛软件赛决赛 C/C++ 大学 B 组 试题 E: 数三角

[蓝桥杯 2023 国 B] 数三角 【问题描述】 小明在二维坐标系中放置了 n n n 个点&#xff0c;他想在其中选出一个包含三个点的子集&#xff0c;这三个点能组成三角形。然而这样的方案太多了&#xff0c;他决定只选择那些可以组成等腰三角形的方案。请帮他计算出一共有多少种选…

凉鞋的 Unity 笔记 101. Hello Unity

101. Hello Unity 学习任何一门技术&#xff0c;第一件事就是先完成 Hello World&#xff01;的输出 所以我们来完成 Unity 的 Hello World。 我们所使用的 Unity 版本是 2023.x 版本。 安装的过程就不给大家展示了。 我们从新建项目开始。 新建项目 打开 Unity Hub 后&…

商圣范蠡见好就收,散尽钱财求得好死

有所得必有所失&#xff0c;有所利必有所害。 人弃我捡&#xff0c;人争我弃。 巴菲特说过&#xff1a;“别人恐惧我贪婪&#xff0c;别人贪婪我恐惧。” 一、商圣 公元前536年&#xff0c;范蠡出生在楚国&#xff0c;家境贫寒。范蠡&#xff0c;字少伯。虽然家里穷&#xf…

大数据Doris(三):Doris编译部署篇

文章目录 Doris编译部署篇 一、Doris编译

装饰器模式详解和实现

装饰器模式&#xff08;Decorator Pattern&#xff09;是一种结构型设计模式&#xff0c;它允许你动态地将对象添加到现有对象中&#xff0c;以提供额外的功能&#xff0c;同时又不影响其他对象。 实现示例 1.定义一个接口或抽象类&#xff0c;表示被装饰对象的公共接口 //抽…

[02] Multi-sensor KIT: DSP 矩阵运算-加法,减法和逆矩阵,放缩,乘法和转置矩阵

1.概述 2.API ◄ arm_mat_init_f32 浮点矩阵初始化 ◄ arm_mat_add_f32 矩阵加法 ◄ arm_mat_mult_f32 矩阵乘法 ◄ arm_mat_inverse_f32 矩阵A的逆矩阵 ◄ arm_mat_scale_f32 矩阵A乘以系数 ◄ arm_mat_inverse_f32 矩阵A减法 ◄ arm_mat_inverse_f32 矩阵A的装置 3.矩阵初…

Spring Security 简单token配置

Spring Security 简单token配置 说明&#xff1a;非表单配置 先上码&#xff1a; https://gitee.com/qkzztx_admin/security-demo/tree/master/demo-two 环境&#xff1a;win10 idea2023 springboot2.7.6 maven3.8.6 代码清单说明 依赖&#xff1a; <dependency><…

mysql报错:Column Count Doesn‘t Match Value Count at Row 1

mysql中执行insert、update、delete报错&#xff1a;Column Count Doesnt Match Value Count at Row 1 的解决方案 通常情况&#xff1a;字段不匹配 如&#xff1a;student有id, name, age字段 -- 错误写法 INSERT INTO student VALUES(5,horse)-- 正确写法 INSERT INTO stu…

【JavaEE】CAS(Compare And Swap)操作

文章目录 什么是 CASCAS 的应用如何使用 CAS 操作实现自旋锁CAS 的 ABA 问题CAS 相关面试题 什么是 CAS CAS&#xff08;Compare and Swap&#xff09;是一种原子操作&#xff0c;用于在无锁情况下保证数据一致性的问题。它包含三个操作数——内存位置、预期原值及更新值。在执…