JAVA反射

本文详细介绍了Java反射的定义、优缺点,以及如何通过Class类、Field类、Method类和Constructor类进行动态操作,包括获取字节码对象、访问属性和方法,以及构造实例。理解反射有助于提高程序灵活性和扩展性。
摘要由CSDN通过智能技术生成

1.反射

1.1.定义

反射Reflection
在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法;并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制,反射使我们在运行时看清一个类的运行情况并使用,反射是Java被视为动态或准动态语言的关键特性反射允许程序在运行时加载、探查、使用一个在编译期可能未知的类

1.2优缺点

(1)优点
运行期类型的判断,动态类加载
提高了程序的灵活性、扩展性,降低耦合性
提高自适应能力,无需提前硬编码目标类

(2)缺点
性能问题
安全限制
内部暴露

1.3.反射API

java.lang包
Class类:反射的核心类,可获取类的属性,方法等信息,生成类的实例
java.lang.reflect包
Field类:表示类的成员变量,可用来获取和设置类的属性值
Method类:表示类的方法,可用来获取类中的方法信息或者执行方法
Constructor类:表示类的构造方法

1.3.1获取类对应的字节码的对象

1.使用Class类中的forName()静态方法(最安全,性能最好)即:Class.forName(“包名+类名”)

try {
            Class c=Class.forName("Net.StudentClass");
            System.out.println("------------------------");
            System.out.println(c.getName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

2.调用某getClass()方法,即:对象.getClass();

StudentClass student = new StudentClass();
        Class c2 = student.getClass();
        System.out.println(c2);

3.调用类的class属性类获取该类对应的Class对象,即:类名.class

Class<StudentClass> c3 = StudentClass.class;
        System.out.println(c3);

1.3.2常用方法

1.获取属性:
getFields() -所有可访问的公共字段
getDeclaredFields() -所有字段
getField(String name) -返回一个特定的公共字段对象

代码实现:

Field[] fields = c.getFields();//只能获取pubic属性
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            System.out.println(field.getName() + "," + field.getType());
        }
        System.out.println("--------------------------------");
        Field[] fields1 = c.getDeclaredFields();//获取所有属性
        for (int i = 0; i < fields1.length; i++) {
            Field field = fields1[i];
            System.out.println(field.getName() + "," + field.getType());
        }
        System.out.println("----------------------------------");
        try {
            Field field = c.getField("grade");//获取指定属性
            System.out.println(field.getName() + field.getType());
            System.out.println("-------------------------------");

2.获取方法:
getMethods()-所有公共方法,包括从超类和超接口继承的声明
getDeclaredMethods() -所有方法,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法
getMethod(String name, Class[] parameterTypes)-返回一个方法对象

Method[] methods = c.getMethods();//获取public方法
//        Method[] methods = c.getDeclaredMethods();
        for (int i = 0; i < methods.length; i++) {
            Method method1 = methods[i];
            System.out.println(method1.getName()+method1.isVarArgs());
        }
        System.out.println("-----------------------------------");
        try {
           // Method printSecr = c.getMethod("getGrade");
            Method printSecr = c.getDeclaredMethod("printSecr");//获取所有方法;
            System.out.println(printSecr.getName());

3.获取构造方法:
getConstructor(Class[] parameterTypes)-返回一个构造方法对象
通过Constructor-newInstance(Object[] initargs)可生成类的实例
通过Method-invoke(Object obj,Object[] args),可在具有指定参数的方法对象上调用此方法对象表示的基础方法

代码实现:

//获取构造方法对象
        //获取person无参构造 方法 的对象
        System.out.println("----------获取无参构造--------------");
        try {
            Constructor constructor = c.getConstructor();
            System.out.println(constructor.getName());
        System.out.println("-----------获取带参构造构造方法的对象---------------");
        Constructor constructor1 = c.getConstructor(new Class[]{String.class, Integer.class, String.class});
            System.out.println(constructor1.getName());

4.调用获取的构造方法调用类的方法,使用invoke(构造方法类)

 Object o = constructor.newInstance();// Object o=new Person()
            System.out.println(o);
            if(o instanceof Person){
                System.out.println("ture");
            }else {
                System.out.println("false");
            }
            Object o1 = constructor1.newInstance(new Object[]{"zhangsan",28,"bosan"});
            System.out.println(o1);

            Constructor constructor2 = c.getConstructor(new Class[]{String.class, Integer.class, Double.class});
            Object o2 = constructor2.newInstance(new Object[]{"李四", 25, 88.8});
            System.out.println(o2);
            Method showMsgMethod = c.getMethod("showMsg");
            System.out.println(showMsgMethod);
            showMsgMethod.invoke(o2,null);
            showMsgMethod.invoke(o,null);
            showMsgMethod.invoke(o1,null);
            System.out.println("----------------------------------------------------");
            Method getNameMethod = c.getMethod("getName");
            Object invoke = getNameMethod.invoke(o2, null);
            System.out.println(invoke);
            System.out.println("------------------------------------------------------");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值