复习java反射

粗略的使用

import com.po.User;

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

public class ReflectionStudyTest {
    public static void main(String[] args) throws Exception {

        /*
            1.源代码阶段使用Class类的静态方法来获取,将字节码文件加入内存返回class对象
            多用于配置文件,在配置文件中加入全限定类名来反射
         */ 

        Class<?> userClass1 = Class.forName("com.po.User");
        System.out.println(userClass1);

        /*
            2.类加载过后可以使用 类名.class来获取
            多用于参数传递
         */
        Class<?> userClass2 = User.class;
        System.out.println(userClass2);

        /*
            3.运行时可以用对象的 。getClass来返回一个class
            用于对象获取字节码文件
         */
        User user = new User("张三", 15);
        Class<?> userClass3 = user.getClass();
        System.out.println(userClass3);

        /*
            一个类在jvm中只有一个class实例:
             同一个字节码文件只会加载一次,3个class一样的
         */
        System.out.println(userClass1 == userClass2);
        System.out.println(userClass2 == userClass3);

        /*
            Class对象功能:
                 获取功能:
                    c1. 获取成员变量们
                         Field[] getFields() :获取所有public修饰的成员变量
                         Field getField(String name)   获取指定名称的 public修饰的成员变量

                         Field[] getDeclaredFields()  获取所有的成员变量,不考虑修饰符
                         Field getDeclaredField(String name)
         */

        Field[] userField = userClass1.getFields();
        for (Field field : userField) {
            System.out.println(field);
        }
        Field a = userClass1.getField("a");
        System.out.println(a);
       /*
        Field:成员变量
            f1. 设置值
                * void set(Object obj, Object value)
            f2. 获取值
                * get(Object obj)

            f3. 忽略访问权限修饰符的安全检查
                * setAccessible(true):暴力反射
         */
        Object value = a.get(user);
        System.out.println("value:" + value);

        a.set(user, 22);
        System.out.println("设置后:" + user);

        Field userName = userClass1.getDeclaredField("name");
        userName.setAccessible(true);//暴力反射
        Object name = userName.get(user);
        System.out.println("name:" + name);

        /*
              c2. 获取构造方法们
                  Constructor<?>[] getConstructors()
                  Constructor<T> getConstructor(类<?>... parameterTypes)

                  Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
                  Constructor<?>[] getDeclaredConstructors()
       Constructor:构造方法
             创建对象:
                 T newInstance(Object... initargs)
                 如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
        */
        //获取构造
        Constructor<?> constructor = userClass1.getConstructor(String.class, int.class);
        User user1 = (User) constructor.newInstance("李四", 20);
        System.out.println("user1:" + user1);
        //一般无参构造
        Constructor<?> constructor1 = userClass1.getConstructor();
        User user2 = (User) constructor1.newInstance();
        System.out.println("user2:" + user2);

        //快速使用无参构造
        Object user3 = userClass1.newInstance();
        System.out.println("user3:" + user3);
        /*
           c3. 获取成员方法们:
                Method[] getMethods()返回所有public方法包括其继承类的公用方法,当然也包括它所实现接口的方法。
                Method getMethod(String name, 类<?>... parameterTypes)

                Method[] getDeclaredMethods()包括所有定义方法,但不包括继承的方法。当然也包括它所实现接口的方法。
                Method getDeclaredMethod(String name, 类<?>... parameterTypes)
	 执行方法:
		 Object invoke(Object obj, Object... args)
	 获取方法名称:
		 String getName:获取方法名
         */
        Method[] userMetheds1 = userClass1.getMethods();
        Method[] userMetheds2 = userClass1.getDeclaredMethods();
        for (Method userMethed : userMetheds2) {
            System.out.println(userMethed);
        }
        Method getName = userClass1.getDeclaredMethod("setName", String.class);
        getName.invoke(user,"改名了");
        System.out.println("user:"+user);
        /*
             c4. 获取全限定类名
                  String getName()
         */
        System.out.println(userClass1.getName());
    }
}

创建一个my.properties

className=com.po.User
methodName=show

测试类

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

public class ReflectionUseTest {
    public static void main(String[] args) throws Exception {
        /*
        可以创建任意类的对象,可以执行任意方法
        不能改变该类的任何代码。可以创建任意类的对象,可以执行任意方法
         */
        //1.加载配置文件
        //1.1创建Properties对象
        Properties pro = new Properties();
        //1.2加载配置文件,转换为一个集合
        //1.2.1获取class目录下的配置文件
        ClassLoader classLoader = ReflectionUseTest.class.getClassLoader();
        InputStream inputStream = classLoader.getResourceAsStream("my.properties");
        pro.load(inputStream);

        //2.获取配置文件中定义的数据
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");


        //3.加载该类进内存
        Class<?> aClass = Class.forName(className);
        //4.创建对象
        Object obj = aClass.newInstance();
        //5.获取方法对象
        Method method = aClass.getMethod(methodName);
        //6.执行方法
        method.invoke(obj);
    }
}

修改配置文件就可以使用任何类的任何方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值