java基础-反射

前言

JAVA反射机制是在运行状态中, 对于任意一个类, 都能够知道这个类的所有属性, 方法, 注解, 继承实现的信息,也就你想要的这里都有. 对于任意一个对象, 都能够调用它的任意方法和属性, 这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制.

反射是学习框架源码之前必须掌握的知识!
本篇主要是介绍api的使用

在线文档.

示例代码github.

反射相关类简介

描述
Class类信息
Field类的属性
Method类的方法
Constructor类的构造器

准备

先建要用到的类

一个父类

public abstract class AbstractClassDemo {
    abstract public void absMethod();
}

一个接口

public interface InterfaceDemo {
    void interfaceMethod();
}

一个类

public class ClassDemo extends AbstractClassDemo implements InterfaceDemo {

    private static String staticField ;

    private final String FINAL_FIELD = "final_field";

    private static final  String STATIC_FINAL_FIELD = "static_final_field";

    private int id;

    private String privateString;

    protected Integer protectedInteger;

    public String publicString;

    public ClassDemo(){

    }

    public String thisPublicMethod(String str) throws ClassCastException,Exception{
        System.out.println("thisPublicMethod " +str);
        return str;
    }

    private static void staticPrivateMethod(String str,String str2){
        System.out.println("staticPrivateMethod " + str +" " +str2);
    }

    @Override
    public void absMethod() {
        System.out.println("absMethod");
    }

    @Override
    public void interfaceMethod() {
        System.out.println("interfaceMethod");
    }

    public void testGetDeclaredClasses(){
        new ClassDemo2().instance().pr();
    }


    public class ClassDemo2{
        public void pr(){

        }

        public ClassDemo2 instance() {
            //匿名内部类
            return new ClassDemo2() {
                @Override
                public void pr(){
                    System.out.println("getDeclaredClasses: " + this.getClass().getDeclaringClass());
                    System.out.println("getEnclosingClass " + this.getClass().getEnclosingClass());
                }
            };
        }

    }

    private class ClassDemo3{

    }

    private static class ClassDemo4{

    }

    public interface InterFace2{

    }
}

Class

	@Test
    void testClass() throws Exception{
		//三种获取类对象的方法 
        //通过Class.forName
        Class clazz = Class.forName("com.xc.java.reflect.ClassDemo");
        System.out.println("通过Class.forName: " + clazz);
        
        //通过 类.class
        Class clazz1 = ClassDemo.class;
        System.out.println("通过 类.class: " + clazz1);

        //通过对象getClass
        Class clazz2 = new ClassDemo().getClass();
        System.out.println("通过对象getClass: " + clazz2);

        //获取类加载器
        ClassLoader classLoader = clazz.getClassLoader();
        System.out.println("类加载器classLoader: " +classLoader);

        //获取内部所有public类,接口
        Class[] classes = clazz.getClasses();
        System.out.println("公共的内部类,接口 getClasses: " + classes);

        //获取内部所有类,接口
        Class[] declaredClasses = clazz.getDeclaredClasses();
        System.out.println("所有的内部类,接口 declaredClasses: " + classes);

        //获取该类实现的接口
        Class[] interfaces = clazz.getInterfaces();
        System.out.println("所有实现的接口getInterfaces: " + classes);

        //获取类的限定类名
        String name = clazz.getName();
        System.out.println("限定类名 getName: " + name);

        //获取类的非限定类名
        String simpleName = clazz.getSimpleName();
        System.out.println("非限定类名 getSimpleName: " + simpleName);

        //获取类所在的包
        Package aPackage = clazz.getPackage();
        System.out.println("获取包 getPackage: " + aPackage);

        //获取直接父类
        Class superclass = clazz.getSuperclass();
        System.out.println("获取父类对象 getSuperclass: " + superclass);

        //父类(或解耦)转换子类
        Class subClazz = clazz.asSubclass(AbstractClassDemo.class);
        System.out.println("父类转子类 subClazz" +subClazz);

        //创建一个对象
        ClassDemo classDemo = (ClassDemo)clazz.newInstance();
        System.out.println("新建一个对象:newInstance " + classDemo);
		
        //getEnclosingClass(支撑匿名内部类) 和 getDeclaringClass(不支持匿名内部类) 都是内部类获取外部类.
        classDemo.testGetDeclaredClasses();
    }

输出结果

通过Class.forName: class com.xc.java.reflect.ClassDemo
通过 类.class: class com.xc.java.reflect.ClassDemo
通过对象getClass: class com.xc.java.reflect.ClassDemo
类加载器classLoader: sun.misc.Launcher$AppClassLoader@18b4aac2
公共的内部类,接口 getClasses: [Ljava.lang.Class;@479d31f3
所有的内部类,接口 declaredClasses: [Ljava.lang.Class;@479d31f3
所有实现的接口getInterfaces: [Ljava.lang.Class;@479d31f3
限定类名 getName: com.xc.java.reflect.ClassDemo
非限定类名 getSimpleName: ClassDemo
获取包 getPackage: package com.xc.java.reflect
获取父类对象 getSuperclass: class com.xc.java.reflect.AbstractClassDemo
父类转子类 subClazzclass com.xc.java.reflect.ClassDemo
新建一个对象:newInstance com.xc.java.reflect.ClassDemo@40ef3420
getDeclaredClasses: null
getEnclosingClass class com.xc.java.reflect.ClassDemo$ClassDemo2

Field

	@Test
    void testField() throws Exception {
        Class clazz = ClassDemo.class;
        Object obj = clazz.newInstance();

        //获取单个属性 public
        clazz.getField("publicString");
        //获取单个属性 private
        clazz.getDeclaredField("publicString");

        //获取类的所有public属性
        Field[] fields = clazz.getFields();
        System.out.println("获取所有public 属性: ");
        for(Field field : fields){
            System.out.println(field.getModifiers() + " " + field.getType().getSimpleName() + " " +field.getName() + " " +field.get(obj));
        }

        //获取所有属性
        Field[] declaredFields = clazz.getDeclaredFields();
        System.out.println("获取所有属性: ");
        for(Field field : declaredFields){

            //设置可访问
            field.setAccessible(true);

            if("publicString".equals(field.getName())){
                //修改公共属性
                field.set(obj,"修改公共属性success");
            }else if("privateString".equals(field.getName())){
                //修改私有属性
                field.set(obj,"修改私有属性success");
            }else if("FINAL_FIELD".equals(field.getName())){
                //修改私有非静态常量
                //modifiers使修饰符的值
                Field modifiers = Field.class.getDeclaredField("modifiers");
                modifiers.setAccessible(true);
                modifiers.setInt(field, field.getModifiers()&~Modifier.FINAL);
                field.set(obj,"修改私有非静态常量success");
            }else if("STATIC_FINAL_FIELD".equals(field.getName())){
                //修改私有静态常量
                Field modifiers = Field.class.getDeclaredField("modifiers");
                modifiers.setAccessible(true);
                modifiers.setInt(field, field.getModifiers()&~Modifier.FINAL);
                field.set(obj,"修改私有静态常量success");
            }
            System.out.println(field.getModifiers() + " "
                    + field.getType().getSimpleName() + " "
                    + field.getName() + " "
                    + field.get(obj));
        }
    }
       /**
     * JAVA 反射机制中,Field的getModifiers()方法返回int类型值表示该字段的修饰符。
     * 对应表如下:
     * PUBLIC: 1
     * PRIVATE: 2
     * PROTECTED: 4
     * STATIC: 8
     * FINAL: 16
     * SYNCHRONIZED: 32
     * VOLATILE: 64
     * TRANSIENT: 128
     * NATIVE: 256
     * INTERFACE: 512
     * ABSTRACT: 1024
     * STRICT: 2048
     */
获取所有public 属性: 
1 String publicString null
获取所有属性: 
10 String staticField null
2 String FINAL_FIELD 修改私有非静态常量success
10 String STATIC_FINAL_FIELD 修改私有静态常量success
2 int id 0
2 String privateString 修改私有属性success
4 Integer protectedInteger null
1 String publicString 修改公共属性success

Method

@Test
    void testMethod() throws Exception{
        Class clazz = ClassDemo.class;
        ClassDemo classDemo = (ClassDemo) (clazz.newInstance());

        //获取所有共有方法
        Method[] methods = clazz.getMethods();
        //获取方法: 通过方法名称 和 ...所有参数类型
        Method thisPublicMethod = clazz.getMethod("thisPublicMethod", String.class);

        //获取方法所有throws异常
        Class[] exceptionTypes = thisPublicMethod.getExceptionTypes();

        //方法所在类
        Class<?> declaringClass = thisPublicMethod.getDeclaringClass();

        //方法参数个数
        int parameterCount = thisPublicMethod.getParameterCount();

        //返回方法所有参数类型
        Class<?>[] parameterTypes = thisPublicMethod.getParameterTypes();

        //返回结果类型
        Class<?> returnType = thisPublicMethod.getReturnType();

        //返回所有Parameter
        Parameter[] parameters = thisPublicMethod.getParameters();

        //获取所有方法
        Method[] declaredMethods = clazz.getDeclaredMethods();

        for (Method declaredMethod : declaredMethods) {
            //设置访问权限
            declaredMethod.setAccessible(true);
            //执行方法
            declaredMethod.invoke(classDemo ,new Object[declaredMethod.getParameterCount()]);
        }
    }

Constructor

@Test
    public void testConstructor() throws Exception{
        Class clazz = ClassDemo.class;

        //获取所有共有构造器
        Constructor[] constructors = clazz.getConstructors();
        System.out.println("获取所有共有构造器 " + constructors);
        //获取所有构造器
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
        System.out.println("获取所有构造器 " + declaredConstructors);

        //根据参数类型和个数获取构造器  public
        Constructor constructor = clazz.getConstructor();
        System.out.println("根据参数类型和个数获取public的构造器  " + constructor);

        //根据参数类型和个数获取构造器
        Constructor declaredConstructor = clazz.getDeclaredConstructor();
        System.out.println("根据参数类型和个数获取构造器 " + declaredConstructor);

        //通过构造器创建一个对象
        Object object = declaredConstructor.newInstance();
        System.out.println("通过构造器创建一个对象 " + object);
    }

输出

获取所有共有构造器 [Ljava.lang.reflect.Constructor;@333291e3
获取所有构造器 [Ljava.lang.reflect.Constructor;@479d31f3
根据参数类型和个数获取public的构造器  public com.xc.java.reflect.ClassDemo()
根据参数类型和个数获取构造器 public com.xc.java.reflect.ClassDemo()
通过构造器创建一个对象 com.xc.java.reflect.ClassDemo@40ef3420

总结

你想要的,反射这里都有.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值