2020-09-19 反射

反射:reflect

Class 类
Field 属性
Method 方法
Constructor 构造方法
package 包
Annotation 注解,可以放在类/属性/方法/构造方法上面,可以放在参数的前面

1.获取Class的三种方式

		try {
            System.err.println(Class.forName("java.lang.String"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.err.println(String.class);
        System.err.println(new String().getClass());

2.Class下的常用方法

2.1 返回此类或接口以整数编码的 Java 语言修饰符。

		int getModifiers() 
		Class clazz = String.class;
        int k = clazz.getModifiers();
        System.out.println(k);

2.2 以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。

		String getName()
		Class clazz = String.class;
        System.out.println(clazz.getName());

2.3 返回源代码中给出的底层类的简称。

		String getSimpleName()
		Class clazz = String.class;
        System.out.println(clazz.getSimpleName());

2.4 获取此类的包

		Package getPackage()
		Class clazz = String.class;
        System.out.println(clazz.getPackage().getName());

2.5 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。

		Class<? super T> getSuperclass()
		Class clazz = String.class;
        System.out.println(clazz.getSuperclass());
demo 获取ArrayList的所有父类
		Class clazz = ArrayList.class;
        while ((clazz = clazz.getSuperclass())!=null){
            System.out.println(clazz);
        }

2.6 确定此对象所表示的类或接口实现的接口。

		Class<?>[] getInterfaces()
		Class clazz = ArrayList.class;
        Class[] classes = clazz.getInterfaces();
        for (Class c: classes) {
            System.out.println(c.getName());
        }

2.7 创建此 Class 对象所表示的类的一个新实例。

调用无参数的构造方法创建对象,如果没有无参数的构造方法,会抛出异常"InstantiationException"

"InstantiationException"产生原因
当应用程序试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象无法被实例化时,抛出该异常。实例化失败有很多原因,包括但不仅限于以下原因:

类对象表示一个抽象类、接口、数组类、基本类型、void
类没有非 null 构造方法
		T newInstance()
		Class clazz = Person.class;
        try {
            Object o = clazz.newInstance();
            System.out.println(o);
        }catch (Exception e) {
            e.printStackTrace();
        }

2.8 返回一个 Field 对象,它反映此 Class 对象所表示的类或接口的指定公共成员字段。

只能找到自己类和父类的public属性

参数的属性名不存在时,会抛出异常“NoSuchFieldException”

		"NoSuchFieldException"产生原因
        类不包含指定名称的字段时产生的信号。
		Field getField(String name)
		Class clazz = Person.class;
        try {
            Field field = clazz.getField("name");
            System.out.println(field);
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

2.9 返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表示的类或接口的所有可访问公共字段。

只能找到自己类和父类的public属性
		Field[] getFields()
		Class clazz = Person.class;
        try {
            Field[] fields = clazz.getFields();
            for (Field f : fields) {
                System.out.println(f);
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

2.10 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。

只能找到自己类的所有属性,任何修饰符修饰的
		Field getDeclaredField(String name)
		try {
            String str = new String("abc");
            System.out.println(str.hashCode()+"-"+str);
            //获得Class
            Class clazz = str.getClass();
            //创建对象
            Object o = clazz.newInstance();
            //获得属性
            Field filed = clazz.getDeclaredField("value");
            //设置私有属性可以直接被操作
            filed.setAccessible(true);
            //修改String的底层数组
            char[] arr = (char[])filed.get(str);
            arr[0] = '1';
            arr[1] = '2';
            arr[2] = '3';
            System.out.println(str.hashCode()+"-"+str);
        } catch (Exception e) {
            e.printStackTrace();
        }

2.12 返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。

只能找到自己类的所有属性,任何修饰符修饰的
		Field[] getDeclaredFields() 

2.13 返回一个 或一组Method 对象

		 
	@Test
    public void test1() throws Exception {
        Class clazz = Person.class;
        //得到本类和父类用public修饰的一个方法
        Method method1 = clazz.getMethod("toString");
        //得到本类和父类用public修饰的一组方法
        Method[] method2 = clazz.getMethods();
        //得到本类和父类用任意修饰符修饰的一个方法
        Method method3 = clazz.getDeclaredMethod("privateXxx");
        //得到本类和父类用任意修饰符修饰的一组方法
        Method[] method4 = clazz.getDeclaredMethods();
    }

2.13 返回一个 或一组Constructor 对象

	@Test
    public void test1() throws Exception {
        Class clazz = Person.class;
        //此时名字不用传递,构造方法有参数则直接传递参数就可以了
        //无参数的构造方法
        Constructor cons = clazz.getConstructor();
        //有参数的构造方法
        Constructor cons2 = clazz.getConstructor(String.class);
        //执行构造方法,构造方法有参数则直接传递参数就可以了
        //执行无参数的构造方法
        cons.newInstance();
        //执行有参数的构造方法
        cons2.newInstance("张三");
        //获取其他修饰符修饰的构造方法
        Constructor cons3 = clazz.getDeclaredConstructor(int.class);
        //如果不是public修饰的,仍要设置setAccessible方法为true
        cons3.setAccessible(true);
        cons3.newInstance(1);
        //获取一组构造方法
		Constructor[] cons4 = clazz.getConstructors();
        Constructor[] cons5 = clazz.getDeclaredConstructors();
        //"构造方法"的常用方法参考"方法"的常用方法
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值