Java反射详解

简介: Java反射详解

反射

1、利用反射访问类构造器

package reflection16;
import java.lang.reflect.Constructor;
/**
 * @ClassName Example_01
 * @Description 访问构造器
 * @Author Zouhuiming
 * @Date 2023/4/14 15:58
 * @Version 1.0
 */
public class Constructor_01{
    public static void main(String[] args) {
        //创建对象
        Example_01 e1 = new Example_01("1", "12", "24");
        //这个是java的泛型,
        //? extends Example_01 表示Class对象是Example_01 类型或者Example_01 的子类
        Class<? extends Example_01> example = e1.getClass();
        //获取所有的构造方法-----getConstructors()只能返回public的构造方法
        Constructor[] constructors=example.getDeclaredConstructors();
        for (int i = 0; i < constructors.length; i++) {
            //获取单个构造器
            Constructor<?> constructor=constructors[i];
            System.out.println("查看是否允许带有可变数量的参数:"+constructor.isVarArgs());
            System.out.println("该构造方法的入口参数类型依次为:");
            //获取构造器的所有参数类型
            Class[] parameterTypes=constructor.getParameterTypes();
            for (int j = 0; j < parameterTypes.length; j++) {
                System.out.println(" "+parameterTypes[j]);
            }
            System.out.println("该构造方法可能抛出的异常类型为:");
            //获取所有可能抛出的异常信息类型
            Class[] exceptionTypes=constructor.getExceptionTypes();
            for (int j = 0; j < exceptionTypes.length; j++) {
                System.out.println(" "+exceptionTypes[j]);
            }
            //声明一个空的Example_01对象
            Example_01 e2=null;
            while (e2==null){
                try{
                    //当i=2时候,利用无参构造器创建一个Example_01对象,并且赋值给e2
                    if (i==2){
                        e2=(Example_01) constructor.newInstance();
                    //当i=1时候,利用两参构造器创建一个Example_01对象,并且赋值给e2
                    }else if (i==1){
                        e2= (Example_01) constructor.newInstance("7",5);
                    //当i=0时候,利用多参构造器创建一个Example_01对象,并且赋值给e2
                    }else {
                        //设置多个参数数组
                        Object[] parameters=new Object[]{new String[] {"100","200","300"}};
                        e2= (Example_01) constructor.newInstance(parameters);
                    }
                } catch (Exception e){
                    System.out.println("在创建对象时抛出异常,下面执行setAccessible()方法");
                    constructor.setAccessible(true);
                }
            }
            if (e2!=null){
                e2.print();
                System.out.println();
            }
        }
    }
}
class Example_01{
    String s;
    int i1,i2,i3;
    private Example_01(){
    }
    protected Example_01(String s,int i){
        this.s=s;
        this.i1=i;
    }
    public Example_01(String...strings) throws NumberFormatException{
        if (0<strings.length)
            i1=Integer.valueOf(strings[0]);
        if (1<strings.length)
            i2=Integer.valueOf(strings[1]);
        if (2<strings.length)
            i3=Integer.valueOf(strings[2]);
    }
    public void print(){
        System.out.println("S="+s);
        System.out.println("i1="+i1);
        System.out.println("i2="+i2);
        System.out.println("i3="+i3);
    }
}

运行截图:

9b8262c19e8d418dbd2e362158e4623b.png

2、利用反射访问类的成员变量

package reflection16;
import java.lang.reflect.Field;
/**
 * @ClassName Method_02
 * @Description 访问成员变量
 * @Author Zouhuiming
 * @Date 2023/4/14 18:00
 * @Version 1.0
 */
public class FieldsOfClass_02 {
    /**1、创建对象
     * 2、获取对象的类
     * 3、获取所有声明的类的成员变量
     * 4、遍历成员变量
     * 5、对成员变量进行操作
     *
     *
     * */
    public static void main(String[] args) {
        Example_02 e=new Example_02();
        //获取e对象的类
        Class e1=e.getClass();
        //获取类的所有声明的变量
        Field[] declaredFields=e1.getDeclaredFields();
        //遍历成员变量数组
        for (int i = 0; i < declaredFields.length; i++) {
            //获取单个成员变量
            Field field=declaredFields[i];
            System.out.println("变量的名称为:"+field.getName());
            //获取成员变量的类型
            Class fieldtype=field.getType();
            System.out.println("成员变量的类型为:"+fieldtype);
//            System.out.println("出错的地方:"+field.getClass());
            boolean isTurn=true;
            while (isTurn){
                //如果该成员变量的访问权限为private,则抛出异常,即不允许访问
                try {
                    isTurn=false;
                    //获取成员变量值
                    System.out.println("成员修改之前的值:"+field.get(e));
                    //判断成员是否是int型
                    if (fieldtype.equals(int.class)){
                        System.out.println("利用setInt()方法去修改变量的值");
                        field.setInt(e,168);
                    }
                    //判断成员是否是float型
                   else if (fieldtype.equals(float.class)){
                        System.out.println("利用setFloat()方法修改变量的值");
                        field.setFloat(e,90.9F);
                        //判断成员是否是boolean型
                    } else if (fieldtype.equals(boolean.class)) {
                        System.out.println("利用setBoolean()方法修改变量的值");
                        field.setBoolean(e,true);
                    }else {
                        System.out.println("利用set去给成员变量赋值(可以给各种类型赋值)");
                        field.set(e,"MWQ");
                    }
                   //获取修改好的值
                    System.out.println("修改之后的值为:"+field.get(e));
                } catch (Exception ex) {
                    System.out.println("在设置成员变量值时抛出异常,下面执行setAccessible()方法");
                    field.setAccessible(true);
                    isTurn=true;
                }
            }
            System.out.println();
        }
    }
}
class Example_02{
    int i;
    public float f;
    protected boolean b;
    private String s;
}

运行截图:

ba13257e317e40009df41577b8367a17.png

3、利用反射访问类的成员方法

package reflection16;
import java.lang.reflect.Method;
/**
 * @ClassName Method_03
 * @Description 访问方法
 * @Author Zouhuiming
 * @Date 2023/4/14 18:32
 * @Version 1.0
 */
public class Method_03 {
    public static void main(String[] args) {
        //创建一个对象
        Example_03 e=new Example_03();
        //利用对象获取类
        Class e1=e.getClass();
        //获取类中所有的方法
        Method[] methods=e1.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            //获取单个方法
            Method method=methods[i];
            System.out.println("方法的名称:"+method.getName());
            System.out.println("方法是否带有可变数量的参数:"+method.isVarArgs());
            System.out.println("入口参数类型依次为:");
            //获取所有参数
            Class[] parameterTypes=method.getParameterTypes();
            for (int i1 = 0; i1 < parameterTypes.length; i1++) {
                System.out.println(" "+parameterTypes[i1]);
            }
            System.out.println("方法的返回值为:"+method.getReturnType());
            System.out.println("可能会抛的异常:");
            Class[] exceptiontypes=method.getExceptionTypes();
            for (int i1 = 0; i1 < exceptiontypes.length; i1++) {
                System.out.println(" "+exceptiontypes[i]);
            }
            boolean isTurn=true;
            while (isTurn){
                try {
                    isTurn=false;
                    if ("staticMethod".equals(method.getName()))
                        method.invoke(e);
                    else if ("publicMethod".equals(method.getName())) {
                        System.out.println("返回值为:"+method.invoke(e,168));
                    } else if ("protectedMethod".equals(method.getName())) {
                        System.out.println("返回值为:"+method.invoke(e,"7",5));
                    }else {
                        Object[] parameters=new Object[]{new String[]{"M","W","Q"}};
                        System.out.println("返回值为:"+method.invoke(e,parameters));
                    }
                } catch (Exception e2){
                    System.out.println("在执行方法时抛出异常,下面执行setAccessible()方法!");
                    method.setAccessible(true);
                    isTurn=true;
                }
            }
            System.out.println();
        }
    }
}
class Example_03{
    static void staticMethod(){
        System.out.println("执行staticMethod()方法");
    }
    public int publicMethod(int i){
        System.out.println("执行publicMethod()方法");
        return i*100;
    }
    protected int protectedMethod(String s,int i){
        System.out.println("执行protectedMethod()方法");
        return Integer.valueOf(s)+i;
    }
    private String privateMethod(String...strings){
        System.out.println("执行privateMethod()方法");
        StringBuffer stringBuffer=new StringBuffer();
        for (int i = 0; i < strings.length; i++) {
            stringBuffer.append(strings[i]);
        }
        return stringBuffer.toString();
    }
}

运行截图:

f898bf3cadc044569d4e28dec399864c.png


相关文章
|
20天前
|
存储 Java
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
13 0
[Java]反射
|
2月前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
62 9
Java——反射&枚举
|
1月前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
25 2
|
2月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
30天前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
16 0
|
2月前
|
Java 程序员 编译器
Java的反射技术reflect
Java的反射技术允许程序在运行时动态加载和操作类,基于字节码文件构建中间语言代码,进而生成机器码在JVM上执行,实现了“一次编译,到处运行”。此技术虽需更多运行时间,但广泛应用于Spring框架的持续集成、动态配置及三大特性(IOC、DI、AOP)中,支持企业级应用的迭代升级和灵活配置管理,适用于集群部署与数据同步场景。
|
2月前
|
存储 安全 Java
扫盲java基础-反射(一)
扫盲java基础-反射(一)
|
2月前
|
Java
扫盲java基础-反射(二)
扫盲java基础-反射(二)
|
4月前
|
安全 Java 测试技术
day26:Java零基础 - 反射
【7月更文挑战第26天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
34 5
|
3月前
|
缓存 安全 Java
【Java 第十篇章】反射
Java 反射技术让程序能在运行时动态获取类信息并操作对象,极大提升了灵活性与扩展性。本文将介绍反射的基本概念、原理及应用,包括如何使用 `Class`、`Field`、`Method` 和 `Constructor` 类进行动态操作。此外,还将探讨反射在动态加载、框架开发与代码测试中的应用场景,并提醒开发者注意性能与安全方面的问题,帮助你更合理地运用这一强大工具。
28 0