java | 反射

反射

定义

在运行期间可以动态的创建对象,获取类型,成员变量,成员方法

如何使用创建

1. 获取class类型信息

  • 方式一: 通过类名.class进行获取

    • 例如:Class stringClass1 = Order.class
  • 方式二: 通过Class的foeName()方法进行获取

    • 例如Class stringClass2 = Class.forName(Order.class)
  • 方式三: 通过对象调用getClass()方法

    • 例如:Class stringClass3"".getCass()

1.1 Class类型的使用场景

  • 获取类名

    • .getClass()
  • 获取包名

    • getPackage().getName()
  • 获取成员变量

    • getDeclaredFields()
  • 获取成员方法

    • getDeclaredMethods()

2. 通过反射进行创建对象

  • 方式一: 直接通过Class对象调用newInstance()方法创建对象

  • 方式二: 通过构造器创建对象,之后再使用newInstance()方法创建对象

    • 获取一组构造器

      • public(公共的)

        • getConstructors()
      • private(私有的)

        • getDeclaredConstructors()
    • 获取指定构造器

      • public(公共的)

        • getConstructor()
      • private(私有的)

        • getDeclaredConstructor()
        • 强行访问:使用setAccessible(true)
    • 获取有参或无参构造器

      • getDeclaredConstructor(String.class, int.class);
      • getDeclaredConstructor();

3. 为成员变量赋值

3.1 方式一、使用反射为私有的成员变量进行赋值
java 复制代码
package com.jiefen.day01;

import java.lang.reflect.Field;

/**
 * @Author 小海
 * @Date: 2024-9-9 19:37
 * @Description: 使用反射为私有的成员变量设置值(不推荐)
 **/
public class AfterInstanceTest05 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {

        //获取class类型信息
        Class ducoClass = Class.forName("com.jiefen.day01.Document"); //获取Class类型信息

        //创建对象
        Object object = ducoClass.newInstance();


        //通过反射拿字段
        Field name = ducoClass.getDeclaredField("name");
        Field age = ducoClass.getDeclaredField("age");

        //访问的私有成员变量,设置访问权限
        name.setAccessible(true);
        age.setAccessible(true);

        //将值设置到对象中在进行赋值
        name.set(object,"博海");
        age.setInt(object,20);


        System.out.println(object);
    }
}
3.2 方式二、使用方法对象的调用
java 复制代码
package com.jiefen.day01;

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

/**
 * @Author 小海
 * @Date: 2024-9-9 19:37
 * @Description: 使用反射为私有的成员变量设置值(方法二,方法对象的调用)
 **/
public class AfterInstanceTest06 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {

        Class ducoClass = Class.forName("com.jiefen.day01.Document"); //获取Class类型信息

        //创建对象
        Object object = ducoClass.newInstance();

        //获取指定名称和参数类型的方法
        Method setName = ducoClass.getMethod("setName", String.class);
        Method setAge = ducoClass.getMethod("setAge", int.class);

        //执行方法
        setName.invoke(object,"你好,我是博海");
        setAge.invoke(object,20);

        System.out.println(object);
    }
}

4. 使用反射调用静态方法

java 复制代码
package com.jiefen.day01;

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

/**
 * @Author 小海
 * @Date: 2024-9-9 19:37
 * @Description: 调用静态方法
 **/
public class AfterInstanceTest07 {
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {

        /**
         * 使用普通的方式进行调用静态方法
         *
         */
        Document.Demo();

        /**
         * 通过反射的方式进行调用静态方法
         */
        Class ducoClass = Class.forName("com.jiefen.day01.Document"); //获取Class类型信息
        Method demo = ducoClass.getMethod("Demo");
        Object invoke = demo.invoke(null);


        /**
         * 普通的方式进行调用静态方法
         */
        String format = String.format("HashMap的默认初始容量是%d,加载因子是%.2f", 16, 0.75);
        System.out.println("使用对象调用了"+format);
        /**
         * 使用反射的方式进行调用静态方法
         */

        Class<String> stringClass = String.class;
        Method format1 = stringClass.getMethod("format", String.class, Object[].class);
        String s = format1.invoke(null, "HashMap的默认初始容量是%d,加载因子是%.2f", new Object[]{16, 0.75}).toString();
        System.out.println("使用反射调用了"+s);

    }
}
相关推荐
重生之我在20年代敲代码11 分钟前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
爱上语文12 分钟前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
serve the people16 分钟前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
qmx_071 小时前
HTB-Jerry(tomcat war文件、msfvenom)
java·web安全·网络安全·tomcat
为风而战1 小时前
IIS+Ngnix+Tomcat 部署网站 用IIS实现反向代理
java·tomcat
编程零零七2 小时前
Python数据分析工具(三):pymssql的用法
开发语言·前端·数据库·python·oracle·数据分析·pymssql
技术无疆3 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
2401_858286113 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
铁松溜达py3 小时前
编译器/工具链环境:GCC vs LLVM/Clang,MSVCRT vs UCRT
开发语言·网络
everyStudy3 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript