Java的反射机制

Java反射

一、反射的概念

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

这里要特别注意,反射是发生在运行时的一种机制

二、反射的功能

 在运行时判断任意一个对象所属的类。
 在运行时构造任意一个类的对象。
 在运行时判断任意一个类所具有的成员变量和方法。
 在运行时调用任意一个对象的成员变量和方法。
 生成动态代理。

三、Demo测试

1.先创建一个User类
package com.muerdh.reflect;

/**
 * User类
 */
public class User {

    // private 修饰的 username
    private String username;

    // public 修饰的 password
    public String password;

    // public 修饰的设置 password 的方法
    public void setPassword(String password) {
        this.password = password;
    }

    // private 修饰的获取 password 的方法
    private String getPassword(){
        return password;
    }
}
2. 反射获取User类的Class对象

有三种方式:全类名.class 、 对象.getClass() 、 Class.forName(“全类名”)

package com.muerdh.reflect;

/**
 * 反射获取User类的Class对象
 */
public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /**
         * 获取User类的Class对象
         */
        //第一种:全类名.class
        Class userClass1 = com.muerdh.reflect.User.class;
        System.out.println("userClass1 = "+userClass1);

        //第二种:对象.getClass();
        Class userClass2 = new User().getClass();
        System.out.println("userClass2 = "+userClass2);

        //第三种:Class.forName("全类名");
        Class userClass3 = Class.forName("com.muerdh.reflect.User");
        System.out.println("userClass3 = "+userClass3);
    }
}

运行结果

userClass1 = class com.muerdh.reflect.User
userClass2 = class com.muerdh.reflect.User
userClass3 = class com.muerdh.reflect.User
3.反射获取类的实例(对象)
package com.muerdh.reflect;

/**
 * 反射获取类的实例(对象)
 */
public class Test2 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException {
        //获取User类的Class对象
        Class userClass = com.muerdh.reflect.User.class;
        System.out.println("userClass = "+userClass);

        //通过User类的Class对象获取User对象,默认调用的是无参构造方法
        User user = (User) userClass.newInstance();
        System.out.println("User = " + user);
    }
}

运行结果

userClass = class com.muerdh.reflect.User
User = com.muerdh.reflect.User@1b6d3586
4.反射获取类得成员变量(private和public修饰的)
package com.muerdh.reflect;

import java.lang.reflect.Field;

/**
 * 反射获取类得成员变量(private和public修饰的)
 */
public class Test3 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchFieldException {
        //获取User类的Class对象
        Class userClass = com.muerdh.reflect.User.class;
        System.out.println("userClass = "+userClass);

        //通过User类的Class对象获取User对象,默认调用的是无参构造方法
        User user = (User) userClass.newInstance();
        System.out.println("User = " + user);

        System.out.println("------------------------------------------------------");

        /**
         * 获取成员变量
         */
        //1.获取单个成员变量
        //通过User类的Class对象获取User类中的成员变量
        Field username = userClass.getDeclaredField("username");
        Field password = userClass.getDeclaredField("password");
        //设置username成员变量可访问(因为User类中的username属性用的是private修饰符),password是public修饰所以不需要设置
        username.setAccessible(true);
        //设置username的值
        username.set(user,"admin");
        password.set(user,"123456");
        System.out.println("username = "+username.get(user)+",password = "+password.get(user));
        System.out.println("username的数据类型:"+username.getType()+"---------password的数据类型:"+password.getType());

        System.out.println("------------------------------------------------------");

        //2.获取多个成员变量
        //通过User类的Class对象获取User类中的所有成员变量
        Field[] userClassDeclaredFields = userClass.getDeclaredFields();
        for (int i = 0; i < userClassDeclaredFields.length ; i++) {
            Field field = userClassDeclaredFields[i];
            //获取成员变量名
            System.out.println("成员变量名:"+field.getName());
        }
    }
}

运行结果

userClass = class com.muerdh.reflect.User
User = com.muerdh.reflect.User@1b6d3586
------------------------------------------------------
username = admin,password = 123456
username的数据类型:class java.lang.String---------password的数据类型:class java.lang.String
------------------------------------------------------
成员变量名:username
成员变量名:password
5.反射获取类中的方法(private和public修饰的)
package com.muerdh.reflect;

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

/**
 * 反射获取类中的方法(private和public修饰的)
 */
public class Test4 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //获取User类的Class对象
        Class userClass = com.muerdh.reflect.User.class;
        System.out.println("userClass = "+userClass);

        //通过User类的Class对象获取User对象,默认调用的是无参构造方法
        User user = (User) userClass.newInstance();
        System.out.println("User = " + user);

        System.out.println("------------------------------------------------------");

        // setPassword方法
        Method setPassword = userClass.getDeclaredMethod("setPassword",String.class);
        System.out.println("方法名:"+setPassword.getName());
        System.out.println("方法的参数列表的数据类型:"+Arrays.toString(setPassword.getParameterTypes()));
        System.out.println("方法参数数量:"+setPassword.getParameterCount());
        System.out.println("方法返回值类型:"+setPassword.getGenericReturnType());
        //调用setPassword方法,第一个参数为user对象,之后的参数为调用方法所需的参数
        setPassword.invoke(user,"123456");

        // getPassword方法
        Method getPassword = userClass.getDeclaredMethod("getPassword");
        //设置getPassword方法可访问(因为User类中的getPassword方法用的是private修饰符),setPassword方法是public修饰所以不需要设置
        getPassword.setAccessible(true);
        System.out.println("password = "+getPassword.invoke(user));
    }
}

运行结果

userClass = class com.muerdh.reflect.User
User = com.muerdh.reflect.User@1b6d3586
------------------------------------------------------
方法名:setPassword
方法的参数列表的数据类型:[class java.lang.String]
方法参数数量:1
方法返回值类型:void
password = 123456
6.反射获取构造方法
package com.muerdh.reflect;

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

/**
 * 反射获取构造方法
 */
public class Test5 {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取User类的Class对象
        Class userClass = com.muerdh.reflect.User.class;
        System.out.println("userClass = "+userClass);

        //获取无参构造,有参构造在getConstructor()中加入所需参数即可
        Constructor userClassConstructor = userClass.getConstructor();
        System.out.println("User的无参构造:"+userClassConstructor);
        System.out.println("User的无参构造-方法名:"+userClassConstructor.getName());
        System.out.println("User的无参构造-方法的参数列表的数据类型:"+ Arrays.toString(userClassConstructor.getParameterTypes()));
        System.out.println("User的无参构造-方法参数数量:"+userClassConstructor.getParameterCount());

        //调用无参构造
        User user = (User) userClassConstructor.newInstance();
        System.out.println("user = " +user);
    }
}

运行结果

userClass = class com.muerdh.reflect.User
User的无参构造:public com.muerdh.reflect.User()
User的无参构造-方法名:com.muerdh.reflect.User
User的无参构造-方法的参数列表的数据类型:[]
User的无参构造-方法参数数量:0
user = com.muerdh.reflect.User@1b6d3586

如有错误,欢迎指正;如有侵权,请联系作者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值