【一】Java之反射机制

本文详细介绍了Java反射机制,包括获取Class对象的三种方式、动态创建对象、操作类的属性、方法以及构造器。通过实例展示了如何通过反射设置和获取对象属性值、调用方法、访问私有成员以及操作构造器。此外,还讨论了反射在提升程序灵活性的同时可能带来的性能影响。
摘要由CSDN通过智能技术生成

Java之反射机制

一、简介

反射由Class类对象开始,从Class对象中,可以获取到有关该类的全部成员的完整列表;可以找出该类的所有类型以及该类实现的接口和扩展的类;可以发现关于类自身的信息,如:修饰符(public、abstract、final等)或者该类所在的包。反射有时也被称为内省,这两个词汇都隐喻了“让类型自我审视并提供自身的描述信息”。这种内省能力也筑就了动态创建和操作对象的第一步。

反射机制能够实现在运行时对类进行加载,增加程序的灵活性,但不恰当的使用反射机制,也会严重影响系统的性能。
反射机制提供的功能主要有:

  • 得到一个对象所属的类;
  • 获取一个类中的所有成员变量和方法;
  • 在运行时创建对象;
  • 在运行时调用对象的方法;

二、实现反射的方法

2.1、获取Class的三种方式

  1. 通过Class.forName(“全类名”);
  2. 类名.class;
  3. 对象名称.getClass();

2.2、操作实例:

package com.mengyb.test.dao;

public class Base {

    private String address;

    public void baseTest1() {
        System.out.println("Base----Test1");
    }

}

package com.mengyb.test.dao;


public class User extends Base{
    private int id;

    public String username;

    public Integer age;

    private String password;

    public User() {
    }

    public User(String username, Integer age) {
        this.username = username;
        this.age = age;
    }

    public void test1() {
        System.out.println("test1----");
    }

    private void privateTest() {
        System.out.println("privateTest----");
    }
    
    public void insert(String username, Integer age) {
        System.out.println("username=" + username + "----------age=" + age);
    }

}

2.3、动态创建类对象

package com.mengyb.test.demotest;


import com.mengyb.test.dao.User;

public class DemoTest1 {
    /**
     * @param args
     */
    public static void main(String[] args) throws Exception {
        System.out.println("--------使用全类名进行获取Bean----------------------");
        Class<?> clazz = Class.forName("com.mengyb.test.dao.User"); //动态加载类。
        //在加载完成后,一般还要调用Class下的newInstance( )静态方法来实例化对象以便操作。
        User newInstance = (User)clazz.newInstance(); 
        newInstance.test1();
        System.out.println("-----------使用对象名称获取Bean-------------------");
        User user = new User();
        Class<? extends User> aClass = user.getClass(); //动态加载类。
        //在加载完成后,一般还要调用Class下的newInstance( )静态方法来实例化对象以便操作。
        User user1 = aClass.newInstance();
        user1.test1();
        System.out.println("-----------使用类名获取Bean-------------------");
        Class clazz2 = User.class; //动态加载类。
        //在加载完成后,一般还要调用Class下的newInstance( )静态方法来实例化对象以便操作。
        User user3 = (User)clazz2.newInstance();
        user3.test1();
    }
}

2.4、对类进行操作

2.4.1、获取类中的属性信息
  public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("com.mengyb.test.dao.User");
        System.out.println("-------------------获取全类名----------------");
        // 获取完整的类名
        String clazzName = clazz.getName();
        System.out.println("全类名----" + clazzName);
        System.out.println("-------------------获取类名----------------");
        // 获取类名
        String clazzSimpleName = clazz.getSimpleName();
        System.out.println("类名----" + clazzSimpleName);
        System.out.println("-------------------获取类中所有的public修饰的Field----------------");
        //获取类中所有的public修饰的Field
        Field[] clazzFields = clazz.getFields();
        for (Field field: clazzFields) {
            System.out.println("field---" + field);
        }

        System.out.println("-------------------获取所有Field----------------");
        // 获取所有Field
        Field[] clazzDeclaredFields = clazz.getDeclaredFields();
        for (Field item: clazzDeclaredFields) {
            System.out.println("DeclaredFields----" + item);
            // 获取Field类型
            Class<?> itemType = item.getType();
            // 获取Field名称
            String itemName = item.getName();
            System.out.println("Field---type---" + itemType + "---------FieldName-----" + itemName);
        }


    }

打印结果
反射操作类Field

2.4.2、对User对象中的属性进行赋值
public static void main(String[] args) throws Exception {
        User user = new User();
        user.age = 12;

        Class<?> clazz = Class.forName("com.mengyb.test.dao.User");
        // newInstance就是一个User对象,底层调用无参构造方法
        Object newInstance = clazz.newInstance();
        // 获取User中的age属性
        Field ageField = clazz.getDeclaredField("age");
        // 为age属性赋值
        ageField.set(newInstance, user.age);

        // 读取age的值
        Object ageValue = ageField.get(newInstance);
        System.out.println("age属性值-----" + ageValue);

        // 访问私有属性
        Field idField = clazz.getDeclaredField("id");
        // 打破封装(不安全) 默认是false
        idField.setAccessible(true);
        idField.set(newInstance, 100);
        Object idValue = idField.get(newInstance);
        System.out.println("id私有属性的值-----" + idValue);
    }

为User对象属性赋值及取值的操作

属性赋值及查看属性值

2.4.3、对Method的操作

    public static void main(String[] args) {
        Class clazz = User.class;

        // 获取User中的所有的方法
        Method[] clazzDeclaredMethods = clazz.getDeclaredMethods();

        // 遍历User中的所有方法
        for (Method method: clazzDeclaredMethods) {
            System.out.println("-----------------------start-------------");
            System.out.println("method-----" + method);

            // 获取方法的修饰符
            int methodModifiers = method.getModifiers();
            System.out.println( "方法的修饰符---" + Modifier.toString(methodModifiers));

            // 获取方法的返回值类型
            Class<?> methodReturnType = method.getReturnType();
            System.out.println("methodReturnType-----" + methodReturnType);

            // 获取方法的名称
            String methodName = method.getName();
            System.out.println("methodName----" + methodName);

            // 获取参数类型列表
            Class<?>[] methodParameterTypes = method.getParameterTypes();
            for (Class item: methodParameterTypes) {
                System.out.println("当前参数类型列表-----" + item.getSimpleName());
            }
            // 获取参数的名称列表
            Parameter[] methodParameters = method.getParameters();
            for (Parameter item: methodParameters) {
                System.out.println("当前参数列表-----" + item.getName());
            }
            System.out.println("-----------------------end-------------");
        }
    }

对方法操作的结果展示

反射获取方法信息的结果展示

2.4.4、通过反射机制对Method进行操作
public static void main(String[] args) throws Exception {
    Class clazz = User.class;
    // 创建对象
    Object newInstance = clazz.newInstance();
    // 获取方法
    Method insertMethod = clazz.getDeclaredMethod("insert", String.class, Integer.class);
    // 调用方法
    insertMethod.invoke(newInstance, "zhangsan", 18);

}

结果展示: username=zhangsan----------age=18

2.4.5、通过反射机制操作构造方法
public static void main(String[] args) throws Exception {
        //
        Class clazz = User.class;


        Constructor[] clazzDeclaredConstructors = clazz.getDeclaredConstructors();

        // 遍历构造方法
        for (Constructor item: clazzDeclaredConstructors) {
            System.out.println("构造方法----" + item.getName());
        }

        Constructor constructor = clazz.getDeclaredConstructor(String.class, Integer.class);
        
        Object newInstance = constructor.newInstance("zhangsan", 18);
        // 查看构造是否生效
        Field username = clazz.getDeclaredField("username");
        System.out.println("username = " + username.get(newInstance));

    }

结果展示
反射构造赋值

2.4.6、通过反射机制查看Bean的父类和接口
public static void main(String[] args) {
        Class clazz = User.class;
        // 
        Class clazzSuperclass = clazz.getSuperclass();
        System.out.println("获取User的父类" + clazzSuperclass);

        Class[] clazzInterfaces = clazz.getInterfaces();
        for (Class item: clazzInterfaces) {
            System.out.println("接口---" + item);
        }
    }

【注】 本章为对反射机制的基本运用,如无法满足需求请查看API文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值