还不会Java反射?让我来带你揭开他的面纱~

笔记整理来源 B站UP主韩顺平https://www.bilibili.com/video/BV1g84y1F7df/?spm_id_from=333.999.0.0&vd_source=763902af33f2b5f3d2e194f3923d02ca

反射

引出反射

image-20220711182208163

image-20220711182529210

/**
 * @author 小黄
 * Date: 2022-07-11
 * Time: 17:45
 * 反射问题的引入
 */
@SuppressWarnings({"all"})
public class ReflectionQuestionDemo {
    public static void main(String[] args) throws ClassNotFoundException, Exception {

        // 根据配置文件 re.properties 指定信息,创建Cat对象并调用hi()方法

        // 传统方式 new 对象 -》调用方法
        // Cat cat = new Cat();
        // cat.hi();
        // 当想调用 cry()方法时 不得已修改源码  ===>>> cat.cry()
        // 在发射中,修改配置文件即可,不需修改源码!!!


        // 1、使用Properties 类,读取配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("BasicGrammer\\src\\re.properties"));
        String classfullpath = properties.getProperty("classfullpath");
        String methodName = properties.getProperty("method");
        System.out.println("classfullpath: " + classfullpath);
        System.out.println("method: " + methodName);

        // 2、创建对象 传统的方法,行不通!!!
        // 错误!!! classfullpath 是字符串!!! String类型
        //new classfullpath()


        // 3、反射机制 解决
        // 3.1、加载类,返回一个Class类型的对象!!!
        Class cls = Class.forName(classfullpath);
        // 3.2、通过 cls 得到你加载的类 com.huang.Cat 的一个对象实例
        Object o = cls.newInstance();
        System.out.println(o.getClass());// 运行类型:com.huang.Cat
        // 3.3、通过 cls.getMethod()方法 得到你加载的类 com.huang.Cat 的 methodName(hi) 的方法对象
        // 即:在反射中,可以将方法视为对象【万物皆对象】
        Method method = cls.getMethod(methodName);
        // 3.4、通过 method 调用方法 【即:通过方法对象来实现调用方法】
        // 传统方法    对象.方法()
        // 反射机制中  方法.invoke(对象)
        System.out.println("=================================================");
        // method.invoke(o) 输出
        // 修改配置文件前:hi 招财猫
        // 修改配置文件后:招财猫 喵喵叫
        method.invoke(o);


    }
}

image-20220711182810968

image-20220711182633533

image-20220711182837506

image-20220711182715447

反射机制在这里插入图片描述

反射机制原理图

image-20220711202527756

image-20220711202705065

反射相关类

image-20220711210416503

image-20220711210441129

反射调用

反射优点和缺点

image-20220711210706762

/**
 * @author 小黄
 * Date: 2022-07-11
 * Time: 21:07
 * 测试反射调用的性能和优化方案
 */
@SuppressWarnings({"all"})
public class ReflectionDemo01 {
    public static void main(String[] args) throws Exception {

        //
        traditionMethod();
        reflectionMethod();
    }


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


    // 反射机制调用hi()方法
    public static void reflectionMethod() throws Exception {
        long start = System.currentTimeMillis();
        Class cls = Class.forName("com.huang.Cat");// 加载类获取Class类实例
        Object o = cls.newInstance();// 获取Class对象实例
        Method hi = cls.getMethod("hi");// 获取方法实例
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("反射机制调用hi()方法耗时:" + (end - start));
    }


}

image-20220711212311904

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

image-20220711213620907

/**
 * @author 小黄
 * Date: 2022-07-11
 * Time: 21:07
 * 测试反射调用的性能和优化方案
 */
@SuppressWarnings({"all"})
public class ReflectionDemo01 {
    public static void main(String[] args) throws Exception {

        //
        traditionMethod();
        reflectionMethod();
        reflectionImprovedMethod();
    }


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


    // 反射机制调用hi()方法
    public static void reflectionMethod() throws Exception {
        long start = System.currentTimeMillis();
        Class cls = Class.forName("com.huang.Cat");// 加载类获取Class类实例
        Object o = cls.newInstance();// 获取Class对象实例
        Method hi = cls.getMethod("hi");// 获取方法实例
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("反射机制调用hi()方法耗时:" + (end - start));
    }

    // 反射机制调用【优化】hi()方法
    public static void reflectionImprovedMethod() throws Exception {
        long start = System.currentTimeMillis();
        Class cls = Class.forName("com.huang.Cat");// 加载类获取Class类实例
        Object o = cls.newInstance();// 获取Class对象实例
        Method hi = cls.getMethod("hi");// 获取方法实例
        hi.setAccessible(true);// 在反射机制调用方法时,取消访问检查
        for (int i = 0; i < 900000000; i++) {
            hi.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("反射机制调用【优化】hi()方法耗时:" + (end - start));
    }

}

image-20220711214337584

Class类分析

image-20220711215117685

image-20220711215232020

/**
 * @author 小黄
 * Date: 2022-07-11
 * Time: 21:44
 * 对Class类特点的梳理
 */
@SuppressWarnings({"all"})
public class ClassDemo01 {
    public static void main(String[] args) throws Exception {

        // 1、Class也是类,因此也继承Object类

        // 2、Class类对象不是new出来的,而是系统创建的
        // 2.1、传统方法 new对象
        Cat cat = new Cat();
        /*
        ClassLoader类
        public Class<?> loadClass (String name) throws ClassNotFoundException {
            return loadClass(name, false);
        }
         */
        // 2.2、反射方式
        Class<?> cls = Class.forName("com.huang.Cat");
        /*
        ClassLoader类,仍然是通过ClassLoader类加载Cat类的 Class对象
        public Class<?> loadClass (String name) throws ClassNotFoundException {
            return loadClass(name, false);
        }
         */

        // 3、对于某个类的Class对象,在内存中只有一份,因为类只加载一次!!!

        // 4、每个类的实例都会记得自己是由哪个Class实例生成的

        // 5、通过Class对象可以完整地得到一个类的完整结构,通过一系列API

        // 6、Class对象是存放在堆里面的

        // 7、类的字节码二进制数据,是放在方法区的,有的地方称为类的元数据(包括 方法代码,变量名,方法名,访问权限等等)

    }
}

Class常用方法

image-20220711230832565

/**
 * @author 小黄
 * Date: 2022-07-11
 * Time: 22:44
 * 演示Class类的常用方法
 */
@SuppressWarnings({"all"})
public class ClassDemo02 {
    public static void main(String[] args) throws Exception {

        // 类的全路径
        String classFullPath = "com.huang.Car";
        // 1、获取到Car类的Class对象
        // 返回与给定字符串名称的类或接口相关联的类对象
        // <?> 表示不确定的Java数据类型
        Class<?> cls = Class.forName(classFullPath);

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        // 2、输出类对象cls
        System.out.println(cls);// 显示cls对象是哪个【类】的Class对象   com.huang.Car

        // 输出其运行类型
        System.out.println(cls.getClass());// java.lang.Class

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        // 3、得到包名
        System.out.println(cls.getPackage().getName());// 包名 com.huang

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        // 4、得到类名
        System.out.println(cls.getName());// 全类名 com.huang.Car

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        // 5、通过cls对象创建对象实例
        Car car = ((Car) cls.newInstance());
        System.out.println(car);// car.toString()

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        // 6、通过反射获取属性 brand
        Field brand = cls.getField("brand");
        System.out.println(brand.get(car));// 宝马

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        // 7、通过反射给字段赋值
        brand.set(car, "奔驰");
        System.out.println(brand.get(car));// 奔驰

        System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
        // 8、遍历得到所有属性(字段)
        Field[] fields = cls.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());// 字段名称
        }


    }
}

获取Class类对象的六种方式

image-20220711234531789

注:根据 Java 程序在计算机中的三个阶段【获取Class类对象方法不同】

image-20220711234731488

image-20220711234749987

image-20220711234810508

/**
 * @author 小黄
 * Date: 2022-07-11
 * Time: 23:13
 * 演示得到Class类对象的各种方式【六种】
 */
@SuppressWarnings({"all"})
public class GetClass {
    public static void main(String[] args) throws Exception {

        // 1、Class.forName()
        // 应用场景:多用于配置文件。读取类全路径,加载类
        String classFullPath = "com.huang.Car";
        Class<?> cls1 = Class.forName(classFullPath);
        System.out.println("cls1: " + cls1);

        // 2、类名.class
        // 应用场景:多用于参数传递。比如通过反射得到对应构造器对象
        Class cls2 = Car.class;
        System.out.println("cls2: " + cls2);

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

        // 4、通过类加载器【四种】来获取类的Class对象
        // (1)、先得到类加载器 Car car
        ClassLoader classLoader = car.getClass().getClassLoader();
        // (2)、通过类加载器得到Class对象
        Class<?> cls4 = classLoader.loadClass(classFullPath);
        System.out.println("cls4: " + cls4);


        // cls1 ,cls2 ,cls3 ,cls4 其实是一个对象
        System.out.println(cls1.hashCode());// 1554874502
        System.out.println(cls2.hashCode());// 1554874502
        System.out.println(cls3.hashCode());// 1554874502
        System.out.println(cls4.hashCode());// 1554874502

        // 5、基本数据类型 按如下方式得到Class类对象
        Class<Integer> integerClass = int.class;
        Class<Boolean> booleanClass = boolean.class;
        Class<Character> characterClass = char.class;
        System.out.println(integerClass);// int

        // 6、基本数据类型对应的包装类,也可以通过 TYPE 得到Class对象
        Class<Integer> type = Integer.TYPE;
        System.out.println(type);// int


        System.out.println(integerClass.hashCode());// 1846274136
        System.out.println(type.hashCode());// 1846274136

       

    }
}

哪些类型有Class类对象

image-20220711235039836

/**
 * @author 小黄
 * Date: 2022-07-11
 * Time: 23:51
 * 演示哪些类型有Class类对象
 */
@SuppressWarnings({"all"})
public class AllTypeClass {
    public static void main(String[] args) {

        // 1、外部类
        Class<String> stringClass = String.class;

        // 2、接口
        Class<Serializable> serializableClass = Serializable.class;

        // 3、数组
        Class<Integer[]> aClass = Integer[].class;
        Class<float[][]> aClass1 = float[][].class;

        // 4、注解
        Class<SuppressWarnings> suppressWarningsClass = SuppressWarnings.class;

        // 5、枚举
        Class<Thread.State> stateClass = Thread.State.class;

        // 6、基本数据类型/包装类
        Class<Integer> integerClass = int.class;
        Class<Integer> integerClass1 = Integer.class;

        // 7、void
        Class<Void> voidClass = void.class;

        // 8、Class【本质也是类】
        Class<Class> classClass = Class.class;

        System.out.println(stringClass);
        System.out.println(serializableClass);
        System.out.println(aClass);
        System.out.println(aClass1);
        System.out.println(suppressWarningsClass);
        System.out.println(stateClass);
        System.out.println(integerClass);
        System.out.println(integerClass1);
        System.out.println(voidClass);
        System.out.println(classClass);
        
        
    }
}

类加载

动态和静态加载

image-20220712085804841

类加载流程图

image-20220712090804518

image-20220712090831224

类加载的五个阶段

加载 Loading

image-20220712092532350

连接 Linking
验证 Verification

image-20220712092718562

准备 Preparation

image-20220712092832115

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

    }
}

@SuppressWarnings({"all"})
class A {

    // 属性-成员变量-字段
    // 分析类加载的 链接-准备阶段 属性是如何处理的
    // 1、n1 是实例属性,不是静态属性,因此在准备阶段,是不会分配内存的
    // 2、n2 是静态属性,会分配内存 n2 默认初始化为0,而不是20
    // 3、n3 是static final 是常量,它和静态变量不一样,因为一旦赋值就不能改变 n3为30
    private int n1 = 10;
    private static int n2 = 20;
    private static final int n3 = 30;

}
解析 Resolution

image-20220712094116497

初始化 Initialization

image-20220712100213335

/**
 * @author 小黄
 * Date: 2022-07-12
 * Time: 9:43
 * 演示类加载-初始化阶段之 <clinit>()方法
 */
@SuppressWarnings({"all"})
public class ClassLoadingDemo {
    public static void main(String[] args) {

        // 1、加载B类,并生成B类的Class对象
        // 2、链接 num = 0
        // 3、初始化
        // 依次自动收集类中的所有静态变量的赋值动作和静态代码块中的语句【按顺序收集并合并!!!】
        /*
         <clinit>(){
            System.out.println("B 的静态代码块被执行");
            num = 500;
            num = 100;
         }
         合并后:num = 100
         */

        System.out.println(B.num);// 100 如果直接使用类的静态属性,也会导致类的加载

    }
}

@SuppressWarnings({"all"})
class B {

    static {
        System.out.println("B 的静态代码块被执行");
        num = 500;
    }

    public static int num = 100;

}

注:在加载类的时候,是有同步机制的!!!

​ 正因为有了这个机制,才能保证某个类在内存中,只有一份Class类对象!!!

image-20220712100934683

获取类结构信息

java.lang.Class类

image-20220712134712242

/**
 * @author 小黄
 * Date: 2022-07-12
 * Time: 10:16
 * 演示如何通过反射类获取类的结构信息
 */
@SuppressWarnings({"all"})
public class ReflectionUtils {
    public static void main(String[] args) {

    }

    @Test
    public void api01() throws Exception {

        // 得到Class类对象
        Class<?> personClass = Class.forName("com.huang.reflection.Person");

        // 1、getName():得到全类名【返回由类对象表示的实体的名称(类,接口,数组类,原始类型或void),作为String 。】
        System.out.println("personClass 全类名:" + personClass.getName());

        // 2、getSimpleName():获取简单类名【返回源代码中给出的基础类的简单名称。】
        System.out.println("personClass 简单类名:" + personClass.getSimpleName());

        // 3、getField():获取所有public修饰的属性,包含本类以及其超类的
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println("本类及其超类public属性名称:" + field.getName());
        }

        // 4、getDeclaredFields():获取本类中所有属性
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类所有属性名称:" + declaredField.getName());
        }

        // 5、getMethods():获取所有public修饰的方法,包含本类以及其超类的
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println("本类及其超类public方法名称:" + method.getName());
        }

        // 6、getDeclaredMethods():获取本类中所有方法
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println("本类所有方法名称:" + declaredMethod.getName());
        }

        // 7、getConstructor():获取本类所有public修饰的构造器【代表这个类的公共构造函数的 Constructor对象的数组】
        Constructor<?>[] constructors = personClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println("本类public构造器名称:" + constructor.getName());
        }

        // 8、getDeclaredConstructors():获取本类所有的构造器
        Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("本类所有的构造器: " + declaredConstructor.getName());
        }

        // 9、getPackage():获取该类所在的包名
        Package personClassPackage = personClass.getPackage();
        System.out.println("该类所在的包名:" + personClassPackage.getName());

        // 10、getSuperclass():获取由该对象表示的类的超类
        Class<?> superclass = personClass.getSuperclass();
        System.out.println("该对象表示的类的超类: " + superclass.getName());

        // 11、getInterfaces():获取这个类实现的接口数组
        Class<?>[] interfaces = personClass.getInterfaces();
        for (Class<?> anInterface : interfaces) {
            System.out.println("该类实现的接口: " + anInterface.getName());
        }

        // 12、getAnnotations():获取此元素上出现的注解
        Annotation[] annotations = personClass.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println("此元素上出现的注解: " + annotation);
        }


    }

}

@SuppressWarnings({"all"})
class C {
    public String hobby;

    public void hi() {

    }

    public C() {

    }
}

@SuppressWarnings({"all"})
interface IC {

}

@SuppressWarnings({"all"})
@Deprecated
class Person extends C implements Serializable, IC {

    // 属性
    public String name;
    protected int age;
    String job;
    private double salary;

    // 方法
    public void m1() {

    }

    protected void m2() {

    }

    void m3() {

    }

    private void m4() {

    }

    // 构造器


    public Person() {

    }

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

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

java.lang.reflect.Filed类

image-20220712134034624

    @Test
    public void api02() throws Exception {

        // 得到Class类对象
        Class<?> personClass = Class.forName("com.huang.reflection.Person");

        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("本类所有属性名称:" + declaredField.getName()
                    + " 该属性的访问修饰符值:" + declaredField.getModifiers()
                    + " 属性类型:" + declaredField.getType());
        }


    }

java.lang.reflect.Method类

image-20220712134049601

    @Test
    public void api03() throws Exception {

        // 得到Class类对象
        Class<?> personClass = Class.forName("com.huang.reflection.Person");

        Method[] declaredMethods = personClass.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);
            }

        }

    }

java.lang.reflect.Constructor类

image-20220712134335636

    @Test
    public void api04() throws Exception {

        // 得到Class类对象
        Class<?> personClass = Class.forName("com.huang.reflection.Person");

        Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println("本类所有的构造器: " + declaredConstructor.getName());

            Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println("该构造器的形参类型:" + parameterType);
            }
        }

    }

反射暴力破解

创建实例

image-20220712142937790

image-20220712143530441

/**
 * @author 小黄
 * Date: 2022-07-12
 * Time: 14:36
 * 演示通过反射机制创建实例
 */
@SuppressWarnings({"all"})
public class ReflectCreateInstance {
    public static void main(String[] args) throws Exception {

        // 1、先获取到User类的Class类对象
        Class<?> userClass = Class.forName("com.huang.reflection.User");

        // 2、通过public的无参构造器创建实例   public User() {// 无参 public
        Object o = userClass.newInstance();
        System.out.println(o);

        // 3、通过public的有参构造器创建实例   public User(String name) {// 有参 public
        Object o1 = userClass.getConstructor(String.class).newInstance("黄孜洋");
        System.out.println(o1);

        // 4、通过非public的有参构造器创建实例    private User(int age, String name) {// 有参 private
        Constructor<?> declaredConstructor = userClass.getDeclaredConstructor(int.class, String.class);
        // 报错 :declaredConstructor构造器私有private!!!
        //Object o2 = declaredConstructor.newInstance(20, "黄孜洋");
        //System.out.println(o2);
        // 解决办法:暴力破解【暴破】
        // 使用反射可以访问私有private的属性/方法/构造器
        // 反射面前,一切都是纸老虎!!!
        declaredConstructor.setAccessible(true);
        Object o3 = declaredConstructor.newInstance(20, "黄孜洋");
        System.out.println(o3);


    }
}

class User {
    private int age;
    private String name;

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

}

操作属性

image-20220712150759617

image-20220712151038438

/**
 * @author 小黄
 * Date: 2022-07-12
 * Time: 15:09
 * 演示反射操作属性/字段
 */
@SuppressWarnings({"all"})
public class ReflectControlField {
    public static void main(String[] args) throws Exception {

        // 1、得到Student类对应的Class类对象
        Class<?> studentClass = Class.forName("com.huang.reflection.Student");

        // 2、创建对象实例
        Object o = studentClass.newInstance();

        // 3、使用反射得到age属性对象
        Field age = studentClass.getField("age");
        // 通过反射操作属性
        age.set(o, 20);
        System.out.println(o);
        System.out.println(age.get(o));

        // 4、使用反射操作name属性【private static】
        Field name = studentClass.getDeclaredField("name");
        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属性


    }
}

@SuppressWarnings({"all"})
class Student {

    public int age;

    private static String name;

    public Student() {
    }

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

}

操作方法

image-20220712153022648

image-20220712153318712

/**
 * @author 小黄
 * Date: 2022-07-12
 * Time: 15:33
 * 演示通过反射调用方法
 */
@SuppressWarnings({"all"})
public class ReflectControlMethod {
    public static void main(String[] args) throws Exception {

        // 1、得到Boss类对应的Class类对象
        Class<?> bossClass = Class.forName("com.huang.reflection.Boss");

        // 2、创建对象
        Object o = bossClass.newInstance();

        // 3、调用 public hi()方法
        Method hi = bossClass.getMethod("hi", String.class);
        hi.invoke(o, "小黄");

        // 4、调用 private static say()方法
        Method say = bossClass.getDeclaredMethod("say", int.class, String.class, char.class);
        say.setAccessible(true);
        Object invoke1 = say.invoke(o, 20, "小黄", '男');
        System.out.println(invoke1);
        System.out.println(invoke1.getClass());
        Object invoke2 = say.invoke(null, 200, "李四", '女');
        System.out.println(invoke2);
        System.out.println(invoke2.getClass());


    }
}

@SuppressWarnings({"all"})
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);
    }

}

反射实操

实操1

image-20220712173839585

实操2

image-20220712173905314

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

eliauk._

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值