反射与注解
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()); } }

浙公网安备 33010602011771号