首页 > 编程语言 >JAVA反射机制【超详细!!】

JAVA反射机制【超详细!!】

时间:2024-09-06 16:53:15浏览次数:7  
标签:-------- 反射 JAVA 构造方法 System 详细 println class1 out

JAVA反射机制

反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射就是把java类中的各种成分映射成一个个的Java对象

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

反射的用途

当我们在使用IDEA时,当我们输入一个对象或者类,并想调用他的属性和方法是,一按点号,编译器就会自动列出他的属性或者方法,这里就是用到反射。

反射的基本使用:

要使用反射,首先要获取类的Class对象。

获得字节码文件对象:主要有三种方法:

  • 对象.getClass()

  • 任何数据类型(包括基本的数据类型)都有一个“静态”的class属性 类.class

  • 通过class类的静态方法:forName(String className)(最常用)

package myreflectDemo1;

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException{

        //第一种 对象.getClass()
        Student student = new Student();
        Class class1 = student.getClass();
        System.out.println(class1);

        //第二种 类名.class
        Class<Student> class2 = Student.class;
        System.out.println(class2);
        //第三种 Class.forName("全类名")
        Class class3 = Class.forName("myreflectDemo1.Student");
        System.out.println(class3);

        //指向同一个地址 都是Student这个类
        System.out.println(class1 == class2);
        System.out.println(class2 == class3);

    }
}

三种方式中,常用第三种,第一种对象都有了还要反射干什么,第二种需要导入类包,依赖太强,不导包就抛编译错误。一般都使用第三种,一个字符串可以传入也可以写在配置文件中等多种方法。

通过反射获取构造方法并使用:

 //        Class类中用于获取当前类构造方法的方法
 //        Constructor[] getConstructors             所有公共的构造方法
 //        Constructor[] getDeclaredConstructors     所有构造方法
 //        Constructor getConstructor                单个公共的构造方法  (只能是公共的)
 //        Constructor getDeclaredConstructor        单个构造方法
package myreflectDemo2;

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

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {

        //访问构造方法  Constructor

        Class class1 = Class.forName("myreflectDemo2.Student");
        //获取当前类class字节码文件对象
        System.out.println("当前类====="+class1);

//        Class类中用于获取当前类构造方法的方法
//        Constructor[] getConstructors             所有公共的构造方法
//        Constructor[] getDeclaredConstructors     所有构造方法
//        Constructor getConstructor                单个公共的构造方法  (只能是公共的)
//        Constructor getDeclaredConstructor        单个构造方法

        //无参和一个参数的构造方法是私有的,两个参数和全参的构造方法是公共的
        System.out.println("--------所有公共的构造方法----------");
        Constructor[] constructors1 = class1.getConstructors();
        for(Constructor con:constructors1){
            System.out.println(con);
        }

        System.out.println("--------所有构造方法----------");
        Constructor[] constructors2 = class1.getDeclaredConstructors();
        for(Constructor con:constructors2){
            System.out.println(con);
        }

        System.out.println("--------单个公共的构造方法----------");
        //空参构造方法是私有的,会报错
//        System.out.println(class1.getConstructor());
        Constructor constructor3 = class1.getConstructor(String.class, int.class);
        System.out.println(constructor3);

        System.out.println("--------单个构造方法----------");
        Constructor constructor4 = class1.getDeclaredConstructor();
        System.out.println(constructor4);


        System.out.println("--------获取构造方法的访问修饰符----------");
        //访问修饰符为1   公共的
        //访问修饰符为2   私有的
        int modifiers1 = constructor3.getModifiers();
        int modifiers2 = constructor4.getModifiers();
        System.out.println("两个参数的构造方法====="+modifiers1);
        System.out.println("无参的构造方法====="+modifiers2);


        System.out.println("--------获取构造方法的参数的个数----------");
        int parameterCount1 = constructor3.getParameterCount();
        int parameterCount2 = constructor4.getParameterCount();
        System.out.println("两个参数的构造方法的参数个数====="+parameterCount1);
        System.out.println("无参的构造方法的参数个数====="+parameterCount2);


        System.out.println("--------获取构造方法创建对象----------");
        Student student1 = (Student)constructor3.newInstance("张三", 18);

        constructor4.setAccessible(true);        // 暴力反射  表示临时取消权限校验
        Student student2 = (Student)constructor4.newInstance();
        System.out.println("两个参数的构造方法=========="+student1);
        System.out.println("无参的构造方法=========="+student2);
    }
}

通过反射获取成员变量并使用:

 //访问成员变量 Field
 ​
 //        Field[] getFields()         获取所有公共的成员变量
 //        Field[] getDeclaredFields() 获取所有公成语变量
 //        Field getField(String name)            获取单个公共的成员变量
 //        Field getDeclaredField (String name)   获取单个成员变量
package myreflectDemo3;

import java.lang.reflect.Field;

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {

        //访问成员变量 Field

//        Field[] getFields()         获取所有公共的成员变量
//        Field[] getDeclaredFields() 获取所有公成语变量
//        Field getField(String name)            获取单个公共的成员变量
//        Field getDeclaredField (String name)   获取单个成员变量

        //获取字节码class文件的对象
        Class class1 = Class.forName("myreflectDemo3.Student");
        System.out.println("--------所有公共的成员变量----------");
        Field[] fields = class1.getFields();
        for (Field field:fields){
            System.out.println(field);
        }

        System.out.println("--------所有成员变量----------");
        Field[] fieldss = class1.getDeclaredFields();
        for (Field field:fieldss){
            System.out.println(field);
        }

        System.out.println("--------单个公共的成员变量----------");
        Field field1 = class1.getField("name");
        System.out.println(field1);



        System.out.println("--------单个成员变量----------");
        Field field2 = class1.getDeclaredField("age");
        System.out.println(field2);

        //获取访问修饰符  getModifiers
        //访问修饰符为1   公共的
        //访问修饰符为2   私有的
        System.out.println("--------成员变量的访问修饰符类别----------");
        int modifiers1 = field1.getModifiers();
        int modifiers2 = field2.getModifiers();
        System.out.println("name访问修饰符======"+modifiers1);
        System.out.println("age访问修饰符======"+modifiers2);


        System.out.println("--------成员变量的数据类型----------");
        Class<?> type1 = field1.getType();
        Class<?> type2 = field2.getType();
        System.out.println("name的数据类型======"+type1);
        System.out.println("age的数据类型======"+type2);

        System.out.println("--------获取成员变量的值----------"); //field1  name的值
        Student student = new Student("张三",18);
        String s = (String) field1.get(student);
        System.out.println("name的值==="+s);

        //用反射修改对象成员变量的值   field1  name的值 "张三"-->"李四"
        System.out.println("--------修改成员变量的值----------");
        field1.set(student,"李四");
        System.out.println("name的值==="+student.name);
    }


}

通过反射获取构成员方法并使用

         //访问成员方法 Method
 ​
 //        Method[] getMethods()         获取所有公共的成员方法
 //        Method[] getDeclaredMethods() 获取所有公成语成员方法
 //        Method getMethod(形参列表)  获取单个公共的成语成员方法
 //        Method getMethod (形参列表)   获取单个成语成员方法
package myreflectDemo4;


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

public class MyReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //访问成员方法 Method

//        Method[] getMethods()         获取所有公共的成员方法
//        Method[] getDeclaredMethods() 获取所有公成语成员方法
//        Method getMethod(形参列表)  获取单个公共的成语成员方法
//        Method getMethod (形参列表)   获取单个成语成员方法

        Class<?> class1 = Class.forName("myreflectDemo4.Student");

        //getMethods() 获取所有公共的成员方法(包含父类的所有公共的成员方法)
        System.out.println("--------所有公共的成员方法----------");
        Method[] methods = class1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

        //getDeclaredMethods()  获取所有成员方法(不能获取父类的,只能获取本类所有的包含私有的成员方法)
        System.out.println("--------所有成员方法----------");
        Method[] declaredMethods = class1.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }

        System.out.println("--------单个公共的成员方法----------");
        Method sleep = class1.getMethod("sleep");
        Method setAge = class1.getMethod("setAge",int.class);
        System.out.println("sleep()方法==="+sleep);
        System.out.println("setAge()方法==="+setAge);

        System.out.println("--------单个成员方法----------");
        Method eat = class1.getDeclaredMethod("eat");
        System.out.println("eat()方法==="+eat);

        //获取方法的访问修饰符  getModifiers
        //访问修饰符为1   公共的
        //访问修饰符为2   私有的
        System.out.println("--------成员方法访问修饰符----------");
        int modifiers = sleep.getModifiers();
        int modifiers1 = eat.getModifiers();
        System.out.println("sleep()方法访问修饰符==="+modifiers);
        System.out.println("eat()方法访问修饰符==="+modifiers1);

        //获取方法的参数个数  getParameterCount()
        System.out.println("--------成员方法参数个数---------");
        int parameterCount = setAge.getParameterCount();
        System.out.println("setAge()方法参数个数==="+parameterCount);

        //获取方法抛出的异常   getExceptionTypes()
        System.out.println("--------成员方法抛出的异常---------");
        System.out.println("sleep方法抛出的异常");
        Class<?>[] exceptionTypes = sleep.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        System.out.println("--------成员方法的返回值---------");
        Student student = new Student();
        Method write = class1.getMethod("write", String.class);
        //invoke  第一个参数表示方法的调用者  第二个参数表示传的参数  返回值就是成员方法的返回值
        String invoke = (String) write.invoke(student, "张三");
        System.out.println(invoke);


    }
}

标签:--------,反射,JAVA,构造方法,System,详细,println,class1,out
From: https://blog.csdn.net/sksnbdkdisbsnskd/article/details/141853236

相关文章

  • JAVA网络编程之InetAddress 和 SocketAddress 的区别
    InetAddress和SocketAddress是Java网络编程中常用的类,用于处理网络连接中的地址信息。1.InetAddressInetAddress用于表示IP地址,既可以是IPV4也可以是IPV6。它可以用来获取主机的IP地址,或根据IP地址查找主机名。InetAddress是抽象类,常用的有两个子类:Inet4Address和I......
  • JavaScript中的Object.freeze()和Object.seal()
    一、Object.freeze()1.简介:Object.freeze()是一个可以将对象冻结的方法。一旦对象被冻结,就不能添加、删除或修改其属性。这在需要确保对象完整性、防止任何意外或故意更改的场景中非常有用constperson={name:'Alice',age:30};Object.freeze(person);p......
  • 搜索算法之二分搜索详细解读(附带Java代码解读)
    1.基本概念二分搜索(BinarySearch)是一种高效的查找算法,用于在一个已排序的数组中查找特定元素。它通过逐步将搜索范围减少一半来实现搜索,从而比线性搜索更快。由于它利用了数组的有序性,能够在对数时间内完成搜索操作。2.工作原理二分搜索的基本思想是:初始化:设置两个指针......
  • JavaScript 循环语句
    1. for 循环for循环是最常用的循环结构之一,它适合在循环开始前就知道循环次数的情况。基本语法for(初始化表达式;条件表达式;迭代后表达式){//循环体//这里的代码会在每次迭代时执行}如何工作初始化:首先执行初始化表达式,通常用来设置循环控制变量。条件......
  • (免费源码)计算机毕业设计必看必学 原创定制程序 java、PHP、python、小程序、文案全套
    摘 要随着互联网趋势的到来,各行各业都在考虑利用互联网将自己推广出去,最好方式就是建立自己的互联网系统,并对其进行维护和管理。在现实运用中,应用软件的工作规则和开发步骤,采用Java技术建设英语自主学习平台。本设计主要实现集人性化、高效率、便捷等优点于一身的英语自......
  • Java集合框架体系
    Java集合类主要由两个接口Collection和Map派生出来的,Collection有三个子接口:List、Set、Queue。Collection:最基本的集合接口,代表一组元素的集合。List:代表有序的、可重复的元素。Set:代表不可重复的的集合。Queue:代表队列Map:存储键值对的集合,键不允许重复。List、Se......
  • java for循环倒序输出
    在Java中,如果你想使用for循环来实现倒序输出(比如倒序输出一个数组或集合中的元素,或者仅仅是从一个数字倒序输出到另一个数字),有几种方法可以实现。下面是一些常见的示例:示例1:倒序输出数组中的元素假设你有一个整数数组,并希望使用for循环来倒序输出数组中的每个元素。int[]numbers......
  • 数据结构练习题(java版)考前必备!
    今天我们刷一些栈队列的题目,大家还是先看题,后看题解。1.155.最小栈-力扣(LeetCode)思路:创建两个栈,一个栈所有元素都算,另一个栈只放小的元素,第二个栈中如果要放的元素比栈顶的元素小就放,这样我们直接pop第二个栈就能得到最小栈classMinStack{publicStack<Integer>......
  • 简易学生信息管理系统课程设计(附源码与详细分析)
    第一章系统概述学生信息管理查询软件是一个教育单位不可缺少的部分它的内容对于学校的决策者和管理者来说都至关重要所以学生信息管理查询软件应该能够为用户提供充足的信息和快捷的查询手段。以前各个学校的学生信息管理基本上都是靠手工进行,但随着各个学校的规模增大,有关学......
  • 算法练习小技巧之有序集合--套路详细解析带例题(leetcode)
    前言:    本文详细讲解Python中的有序集合SortedList和C++中的有序集合multiset的用法,配合leetcode的例题来展示实际的用处。(本人水平不够,还无法讲解有序集合的实现方法,只会用)    觉得有帮助或者写的不错可以点个赞,后面也有几道我找出来的题目可以用这个方......