[JAVA反射的用法]

 反射的定义

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

        反射的原理是,通过类获取类的Class对象,Class对象通过反编译获取对象中的包名、类名、属性名、方法名、构造器(包括私有的属性和方法)。利用反射机制,类对我们来说就是透明的,可以得到任何我们想得到的东西。

反射的优点
  • 可以在程序运行过程中,操作这些对象;
  • 可以解耦,提高程序的可扩展性。

反射的用法
package com.dong.flaw.demo;

import java.util.Arrays;
import java.util.concurrent.Flow;

/**
 * @author 冬日的暖阳
 * @date 2024/8/6 20:58
 * @apiNote
 */
public class Student implements Flow.Processor{

    // ----------------------- 字段 -------------------------------
    public String name;

    protected int age;

    char sex;

    private String phoneNum;



    // ----------------------- 构造方法 ----------------------------------

    /**
     * 默认构造方法
     * @param str
     * @return
     */
    Student(String str){
        System.out.println(("默认的构造方法 s = " + str));
    }


    /**
     * 无参构造方法
     */
    public Student(){
        System.out.println("调用公有、无参构造方法。。。。。");
    }


    /**
     * 一个参数的构造方法
     * @param name
     */
    public Student(char name){
        System.out.println("姓名:"+name);
    }


    /**
     * 多个参数的构造方法
     * @param name
     * @param age
     */
    public Student(String name , int age){
        System.out.println("姓名:"+name+" , 年龄:"+age);
    }


    /**
     * 受保护的构造方法
     * @param bool
     */
    protected Student(boolean bool){
        System.out.println("受保护的构造方法 n = "+ bool);
    }


    /**
     * 私有构造方法
     * @param age
     */

    private Student(int age){
        System.out.println("私有构造方法 age = "+ age);
    }


    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", phoneNum='" + phoneNum + '\'' +
                '}';
    }



    public void show1(){
        System.out.println("公有方法调用");
    }


    protected void show2(){
        System.out.println("受保护方法调用方法调用");
    }


    private void show3(int num){
        System.out.println("私有方法调用:"+ num);
    }

    private void show4(){
        System.out.println("无参私有方法调用");
    }


    public static void main(String[] args) {
        System.out.println("执行main方法:"+ Arrays.toString(args));
    }


    @Override
    public void subscribe(Flow.Subscriber subscriber) {

    }

    @Override
    public void onSubscribe(Flow.Subscription subscription) {

    }

    @Override
    public void onNext(Object item) {

    }

    @Override
    public void onError(Throwable throwable) {

    }

    @Override
    public void onComplete() {

    }
}

    /**
     * 通过反射获取类的三种方式
     * @throws ClassNotFoundException
     */
    @Test
    public void getClassName() throws ClassNotFoundException {
        Student student1 = new Student();
        Class class1 = Class.forName("com.dong.flaw.demo.Student");
        Class class2 = student1.getClass();
        Class class3 = Student.class;
        System.out.println(class1);
        System.out.println(class2);
        System.out.println(class3);
    }

/**

调用公有、无参构造方法。。。。。
class com.dong.flaw.demo.Student
class com.dong.flaw.demo.Student
class com.dong.flaw.demo.Student

*/









    /**
     * 通过反射获取类的包名
     */
    @Test
    public void getPackage(){
        try {
            Class class1 = Class.forName("com.dong.flaw.demo.Student");
            Package packageName = class1.getPackage();
            System.out.println("Student类的包名:"+packageName);
        }catch (Exception e){
            e.printStackTrace();
        }
    }


/**

Student类的包名:package com.dong.flaw.demo

*/









    /**
     * 通过反射获取类的作用域
     */
    @Test
    public void getScope(){
        try {
            Class className = Student.class;
            int modifiers = className.getModifiers();
            // 将int类型的作用域转化为String类型
            String modifier = Modifier.toString(modifiers);
            System.out.println("Student类的作用域为:"+modifier);
        }catch (Exception e){
            e.printStackTrace();
        }
    }



/**

Student类的作用域为:public

*/







    /**
     * 通过反射获取类名
     */
    @Test
    public void getClassSimpleName(){
        Class className = new Student().getClass();
        String classSimpleName = className.getSimpleName();
        System.out.println("Student的类名:"+classSimpleName);
    }


/**

调用公有、无参构造方法。。。。。
Student的类名:Student

*/








    /**
     * 通过反射获取继承的类名
     */
    @Test
    public void getExtend(){
        Class className = Student.class;
        String extendName = className.getSuperclass().getSimpleName();
        System.out.println("Student继承父类为:"+extendName);
    }


/**

Student继承父类为:Object

*/






    /**
     * 通过反射获取实现的接口名
     */
    @Test
    public void getImplements(){
        Class className = Student.class;
        Class[] implementArr = className.getInterfaces();
        for (Class implement : implementArr){
            System.out.print("Student实现接口有:" + implement.getSimpleName()+"\t\t");
        }

    }



/**

Student实现接口有:Processor	

*/









    /**
     * 通过反射获取类的构造函数
     */
    @Test
    public void structural(){
        try {
            // 获取class对象
            Student student = new Student();
            Class className = student.getClass();


            // 获取所有公有构造方法
            Constructor[] constructors = className.getConstructors();
            for (Constructor constructor : constructors){
                System.out.println("公有的无参构造函数:"+constructor);
            }
            System.out.println();


            // 获取所有构造方法
            constructors = className.getDeclaredConstructors();
            System.out.println("调用所有构造方法。。。。。。");
            for (Constructor c : constructors){
                System.out.println("所有的构造函数:"+c);
            }
            System.out.println();



            // 获取公有无参构造
            Constructor constructor = className.getConstructor();
            System.out.println("调用公有无参构造方法");
            System.out.println(constructor);
            System.out.println();


            // 获取私有构造方法
            Constructor constructor1 = className.getDeclaredConstructor(int.class);
            System.out.println("私有的带参数的构造函数,并传值调用:"+constructor1);
            constructor1.setAccessible(true);
            constructor1.newInstance(20);


        }catch (Exception e){
            e.printStackTrace();
        }
    }



/**

调用公有、无参构造方法。。。。。
公有构造函数:
public com.dong.flaw.demo.Student(char)
public com.dong.flaw.demo.Student()
public com.dong.flaw.demo.Student(java.lang.String,int)

调用所有构造方法。。。。。。
com.dong.flaw.demo.Student(java.lang.String)
private com.dong.flaw.demo.Student(int)
protected com.dong.flaw.demo.Student(boolean)
public com.dong.flaw.demo.Student(char)
public com.dong.flaw.demo.Student()
public com.dong.flaw.demo.Student(java.lang.String,int)

调用公有无参构造方法
public com.dong.flaw.demo.Student()

私有的带参数的构造函数,并传值调用:private com.dong.flaw.demo.Student(int)
私有构造方法 age = 20

*/








    /**
     * 通过反射获取类的成员变量
     */
    @Test
    public void getFields(){
        try {
            Student student = new Student();
            Class className = student.getClass();


            // 获取公有的字段属性
            Field[] fields = className.getFields();
            System.out.print("获取公有的字段属性:");
            for (Field field : fields){
                System.out.println(field.getName() + "\t\t");
            }
            System.out.println();


            // 获取所有的字段属性
            Field[] fields1 = className.getDeclaredFields();
            System.out.print("获取所有的字段属性:");
            for (Field field : fields1){
                System.out.print(field.getName() + "\t\t");
            }
            System.out.println("\n");


            // 获取指定字段,并调用
            Field name = className.getDeclaredField("name");
            System.out.println("获取类字段,并赋值:"+ name.getName());
            // 获取对象
            Object obj = className.getConstructor().newInstance();
            name.set(obj,"牛");
            Student stu =  (Student) obj;
            System.out.println("name属性:"+stu.name);
            System.out.println("\n");


            // 作用域:protected
            Field age = className.getDeclaredField("age");
            age.setAccessible(true);
            age.set(obj,25);


            // 作用域:private
            Field phoneNum = className.getDeclaredField("phoneNum");
            // 授权,允许访问私有变量
            phoneNum.setAccessible(true);
            phoneNum.set(obj,"123456");


            // 默认属性
            Field sex = className.getDeclaredField("sex");
            sex.setAccessible(true);
            sex.set(obj,'男');


            System.out.println("打印对象:"+ stu);
        }catch (Exception e){
            e.printStackTrace();
        }
    }



/**

调用公有、无参构造方法。。。。。
获取公有的字段属性:name		

获取所有的字段属性:name		age		sex		phoneNum		

获取类字段,并赋值:name
调用公有、无参构造方法。。。。。
name属性:牛


打印对象:Student{name='牛', age=25, sex=男, phoneNum='123456'}



*/







/**
     * 通过反射获取类的成员方法
     */
    @Test
    public void getMethods(){
        try {
            Class className = Class.forName("com.dong.flaw.demo.Student");

            // 获取方法
            Method[] methods = className.getMethods();
            System.out.println("公有方法。。。。。。");
            for (Method method : methods){
                System.out.print(method.getName()+"\t\t");
            }
            System.out.println("\n");


            // 所有方法
            Method[] methods1 = className.getDeclaredMethods();
            System.out.println("所有方法。。。。。。。。");
            for (Method method : methods1){
                System.out.print(method.getName()+"\t");
            }
            System.out.println("\n");


            // 私有方法,并调用
            Method method = className.getDeclaredMethod("show3",int.class);
            System.out.println();
            System.out.println("私有方法......."+method.getName());
            method.setAccessible(true);
            method.invoke(className.newInstance(),45);
            System.out.println();


            // 调用无参私有方法
            Method method1 = className.getDeclaredMethod("show4");
            System.out.println("无参私有方法:"+method1.getName());
            method1.setAccessible(true);
            method1.invoke(className.newInstance(),null);
        }catch (Exception e){
            e.printStackTrace();
        }

    }



/**

公有方法。。。。。。
main		toString		onNext		show1		onError		onSubscribe		subscribe		onComplete		wait		wait		wait		equals		hashCode		getClass		notify		notifyAll		

所有方法。。。。。。。。
show3	show4	main	toString	show2	onNext	show1	onError	onSubscribe	subscribe	onComplete	


私有方法.......show3
调用公有、无参构造方法。。。。。
私有方法调用:45

无参私有方法:show4
调用公有、无参构造方法。。。。。
无参私有方法调用

*/













     /**
     * 通过反射获取并执行main方法
     */

    @Test
    public void getMain(){
        try {
            Class<Student> className = Student.class;

            String[] a = new String[]{"1","2"};

            // 获取main方法
            Method main = className.getMethod("main", String[].class);
            System.out.println("main方法:"+main.getName());
            main.invoke(null,(Object)a);
        }catch (Exception e){
            e.printStackTrace();
        }
        
    }


/**

main方法:main
执行main方法:[1, 2]

*/



















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值