Java的反射机制(源码)

一、什么是反射?

  Java反射说的是在运行状态中,对于任何一个类,我们都能够知道这个类的所有方法和属性;对于任何一个对象,我们都能够对它的方法和属性进行调用。我们把这种动态获取对象信息和调用对象方法的功能称之为反射机制。

二、反射获取类的三种方式

  反射其实是获取类的字节码文件,也就是JVM可以识别加载.class文件。
  通过Class<?>获取类信息。

1. 通过className.class获取

package test;

public class ClassTest {
    public static void main(String[] args) {
        Class<?> clazz = User.class;
        System.out.println(clazz.getName());  //test.User
    }                                         //name就是他的路径名(包名.类名)
}
    class User {
        int i = 0;
    }

2. 通过Object.getClass()获取

package test;

public class ClassTest {
    public static void main(String[] args) {
        User user = new User();
        Class<?> clazz = user.getClass();
        System.out.println(clazz.getName());  //test.User
    }										  //name就是他的路径名(包名.类名)
}
    class User {
        int i = 0;
    }

3. 通过Class.forName(“类的路径”)获取

package test;

public class ClassTest {              //需要抛出异常,根据路径可能会找不到这个类
    public static void main(String[] args) throws ClassNotFoundException {
        Class<?> clazz = Class.forName("test.User");
        System.out.println(clazz.getName());  //test.User
    }										  //name就是他的路径名(包名.类名)
}
    class User {
        int i = 0;
    }

第一种需要导入类的包,依赖性太强。
第二种已经创建了对象,那么这个时候就不需要进行反射了。
所以我们一般选中第三种方式,架构一般用这种方式。

三、通过反射获取类的属性、方法以及构造方法

1. 获取类的属性

package test;

import java.lang.reflect.Field;

public class ClassTest {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("test.User");

        System.out.println("*******获取所有公共字段******");
        Field i = clazz.getField("i");            //获取类的公共字段的特定属性
        Field[] fields = clazz.getFields();       //获取类的公共字段的所有属性

        System.out.println("*******获取所有声明字段******");
        Field field = clazz.getDeclaredField("i");         //获取类的声明字段的特定属性
        Field[] declaredFields = clazz.getDeclaredFields();//获取类的声明字段的所有属性


        System.out.println("*******获取私有属性并使用******");
        Object object = clazz.getConstructor().newInstance();
        field.setAccessible(true);   //假如不是私有属性则没有这一行
        field.set(object,2);

        User user = (User) object;
        System.out.println(user.i);
    }
}
    class User {
       private int i = 0;
    }

2. 获取类的方法

package test;

import java.lang.reflect.Method;

public class ClassTest {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("test.User");

        System.out.println("*******获取公共方法******");
        Method publicMethod = clazz.getMethod("publicMethod"); //获取类的公共方法的特定方法
        Method[] methods = clazz.getMethods();           //获取类的公共方法的所有方法

        System.out.println("*******获取声明方法******");
        Method declaredMethod = clazz.getDeclaredMethod("privateMethod");  //获取类的声明方法的特定方法
        Method[] declaredMethods = clazz.getDeclaredMethods();   //获取类的声明方法的所有方法


        System.out.println("*******获取私有方法并使用******");
        Object object = clazz.getConstructor().newInstance();
        declaredMethod.setAccessible(true);                 //将方法设为可访问
        Object invoke = declaredMethod.invoke(object);    //通过invoke()调用方法
    }
}
    class User {
        public void publicMethod(){
           System.out.println("测试public方法");
        }
        private void privateMethod(){
            System.out.println("测试private方法");
        }
    }

3. 获取类的构造方法

package test;

import java.lang.reflect.Constructor;

public class ClassTest {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("test.User");

        System.out.println("*******获取公共的无参构造方法******");
        Constructor<?> constructor = clazz.getConstructor(null);
        Constructor<?>[] constructors = clazz.getConstructors();

        System.out.println("*******获取声明的无参构造方法******");
        Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(null);
        Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();


        System.out.println("*******构造方法的使用******");
        Object object = clazz.getConstructor().newInstance();

    }
}
    class User {
        int i = 0;

        public User() {
            
        }
    }

四、反射的方法源码

1. 获取类的属性

@CallerSensitive
    public Field getField(String name)
        throws NoSuchFieldException, SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        Field field = getField0(name);
        if (field == null) {
            throw new NoSuchFieldException(name);
        }
        return field;
    }
@CallerSensitive
    public Field[] getFields() throws SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        return copyFields(privateGetPublicFields(null));
    }
    @CallerSensitive
    public Field getDeclaredField(String name)
        throws NoSuchFieldException, SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        Field field = searchFields(privateGetDeclaredFields(false), name);
        if (field == null) {
            throw new NoSuchFieldException(name);
        }
        return field;
    }
   @CallerSensitive
    public Field[] getDeclaredFields() throws SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        return copyFields(privateGetDeclaredFields(false));
    }

2. 获取类的方法

    @CallerSensitive
    public Method getMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        Method method = getMethod0(name, parameterTypes, true);
        if (method == null) {
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
        }
        return method;
    }
    @CallerSensitive
    public Method[] getMethods() throws SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        return copyMethods(privateGetPublicMethods());
    }
    @CallerSensitive
    public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
        if (method == null) {
            throw new NoSuchMethodException(getName() + "." + name + argumentTypesToString(parameterTypes));
        }
        return method;
    }
    @CallerSensitive
    public Method[] getDeclaredMethods() throws SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        return copyMethods(privateGetDeclaredMethods(false));
    }

3. 获取类的构造方法

    @CallerSensitive
    public Constructor<T> getConstructor(Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        return getConstructor0(parameterTypes, Member.PUBLIC);
    }
    @CallerSensitive
    public Constructor<?>[] getConstructors() throws SecurityException {
        checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
        return copyConstructors(privateGetDeclaredConstructors(true));
    }
    @CallerSensitive
    public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
        throws NoSuchMethodException, SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        return getConstructor0(parameterTypes, Member.DECLARED);
    }
    @CallerSensitive
    public Constructor<?>[] getDeclaredConstructors() throws SecurityException {
        checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
        return copyConstructors(privateGetDeclaredConstructors(false));
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值