反射与注解

1.反射的理解主要通过老师的讲义和

https://www.bilibili.com/video/BV15J411s7kz/?spm_id_from=333.337.search-card.all.click&vd_source=af888e4b9fbc70c4d5e7a445796ae8a1

这个视频,对比学习。

2.关于可变形参的定义和注意点可变形参与数组的区别数组形参的注意点反射的底层逻辑与用途,讲义笔记文档(E盘)中都写了,这里就不赘述了。

3.常见的反射功能:(这里的clazz代表某个class构建的对象)

(1)clazz.getDeclaredConstructors()  -------  获取该class对象所对应的全部构造器(就是所有与类名相同的有参、无参方法)

(2)clazz.getConstructors()  -------  获取该class对象所对应的全部public构造器

(3)clazz.getMethods()  -------  获取该class对象所对应的全部public方法

(4)clazz.getMethod("要找的方法名",[相关参数])  -------  寻找该class对象所对应类中指定的方法

(5)clazz.getDeclaredClasses()  -------  获取该Class对象所对应类的全部内部类

(6)Class.forName([指定类名])  -------  加载ClassTest的指定内部类

(7)clazz.getDeclaringClass()  -------  获取clazz对应类的外部类

(8)clazz.getPackage()  -------  获取clazz对应类的包

(9)clazz.getSuperclass()  -------  获取clazz对应类的父类

4.java8新增的方法参数反射:

新增了API获取函数的注解信息、抛出的异常类信息、函数参数信息、函数的修饰符

比如:

isVarArgs():判断函数是否包含可变形参,

getModifiers():获取函数的修饰符。

int getParameterCount():获取函数的形参个数。

Parameter[] getParameters():获取函数的所有形参。

记得要在java编辑器中指定默认-parameters参数

5.通过反射执行代码的常用方式:

① 通过反射调用构造器创建对象。(一般需要动态创建某个类的对象时才会考虑用反射,通常在开发通用性比较广的框架和基础平台时可能会大量使用反射。

② 通过反射调用方法(可以通过将setAccessible(boolean flag)设为特定布尔值来访问private类)---控制反转IOC

③ 通过反射来访问成员变量值(通过Class对象的getFields()getField()方法获取

④ 通过反射操作数组(可以是数组也可以是可变形参,可以通过反射动态创建、操纵数组)

6.小知识点:

1.Class<Integer>,<>中表示该类的类型
  Class<?>表示不确定的java类型
2.Class.forName("类的全限定名"),使用此方法获得与字符串相应的class对象,其中的字符串必须是借口或类的名字,以string类型返回class对象表示的实体名称
常用的
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

public class ClassTest {
    // 为该类定义一个私有的构造器
    private ClassTest() {
    }

    // 定义一个有参数的构造器
    public ClassTest(String name) {
        System.out.println("执行有参数的构造器");
    }

    // 定义一个无参数的info方法
    public void info() {
        System.out.println("执行无参数的info方法");
    }

    // 定义一个有参数的info方法
    public void info(String str) {
        System.out.println("执行有参数的info方法" + ",其str参数值:" + str);
    }

    // 定义测试用的内部类
    class Inner {
    }

    class Inner2 {
    }

//Class<Integer>,<>中表示该类的类型
//Class<?>表示不确定的java类型

    public static void main(String[] args) throws Exception {
        // 下面代码可以获取ClassTest对应的Class
        Class<ClassTest> clazz = ClassTest.class;
        // 获取该Class对象所对应类的全部构造器
        Constructor[] ctors = clazz.getDeclaredConstructors();
        System.out.println("ClassTest的全部构造器如下:");
        for (Constructor c : ctors) {
            System.out.println(c);
        }
        // 获取该Class对象所对应类的全部public构造器
        Constructor[] publicCtors = clazz.getConstructors();
        System.out.println("ClassTest的全部public构造器如下:");
        for (Constructor c : publicCtors) {
            System.out.println(c);
        }
        // 获取该Class对象所对应类的全部public方法
        Method[] mtds = clazz.getMethods();
        System.out.println("ClassTest的全部public方法如下:");
        for (Method md : mtds) {
            System.out.println(md);
        }
        // 获取该Class对象所对应类的指定方法
        System.out.println("ClassTest里带一个字符串参数的info()方法为:" + clazz.getMethod("info", String.class));

        // 获取该Class对象所对应类的全部内部类
        Class<?>[] inners = clazz.getDeclaredClasses();
        System.out.println("ClassTest的全部内部类如下:");
        for (Class<?> c : inners) {
            System.out.println(c);
        }

//Class.forName("类的全限定名"),使用此方法获得与字符串相应的class对象,
//其中的字符串必须是借口或类的名字,
//以string类型返回class对象表示的实体名称

        // 使用Class.forName方法加载ClassTest的Inner内部类
        Class inClazz = Class.forName("springmvcdemo1.ClassTest$Inner");
        // 通过getDeclaringClass()访问该类所在的外部类
        System.out.println("inClazz对应类的外部类为:" + inClazz.getDeclaringClass());
        System.out.println("ClassTest的包为:" + clazz.getPackage());
        System.out.println("ClassTest的父类为:" + clazz.getSuperclass());
    }
}

 

posted @ 2023-09-21 15:51  PeeledPotato  阅读(28)  评论(0)    收藏  举报