1.反射注解:注解的在jdk1.5版本中更新,产生可以提高代码的功能性,因为他有解释功能的作用,之后在学习中我们还可以发现有了注解,我们可以代替很多配置文件,通过运行期间,反射可以动态的绑定数据。
反射:是JAVA一个非常突出的动态相关机制:Reflection,在阅读底层代码时,很多都是用反射来实现的,它可以动态的帮我做一些琐事,而我们可以不关注如何实现,只需要去用就行,比如SpringBoot。
JVM得到class对象,再通过class对象反编译得到得到对象的各种信息。
反射是一种程序运行期间的行为
构建Class对象Class.forName("包路径+类型");类型.class;对象.getClass()
//引用数据类型
Class string1 = String.class;
Class string2 = Class.forName("java.lang.String");
Class string3 = "".getClass();
System.out.println((string1 == string2 && string1 == string3));
//基本数据类型
Class int1 = int.class;
Class integerClass1 = Integer.class;
//(Class) Class.getPrimitiveClass("int") 缺省 不能直接调用
Class integerClass2 = Integer.TYPE;
Class integerClass3 = Class.forName("java.lang.Integer");
System.out.println(integerClass1);
System.out.println(integerClass2.toString());
System.out.println(integerClass3);
System.out.println(int1);
//(isInterface() ? "interface " : (isPrimitive() ? "" : "class ")) //判断是不是接口 基本数据类型
// + getName();
通过反射构建对象
调用方法1. 通过class对象直接newInstance() 默认调用空构造为对象初始化信息-->不推荐使用
2. 通过构造器 调用newInstance() 构建原有对象
getConstructor() 类对象所表示的类的指定公共构造函数getConstructors() 类对象所表示的类的所有公共构造函数getDeclaredConstructor() 类对象所表示的类的指定任意构造函数 getDeclaredConstructors() 类对象所表示的类的所有构造函数
//不推荐使用 因为不知道该类型是否存在无参构造器 Employee employee = Employee.class.newInstance(); //获取构造器 ClassemployeeClass = Employee.class; Constructor[] cons = employeeClass.getConstructors(); System.out.println(Arrays.toString(cons)); System.out.println("---------------"); //获取指定的私有方法 Constructor con = employeeClass.getDeclaredConstructor(int.class,String.class); //因为是私有方法 需要需略访问权限再使用 con.setAccessible(true); Employee emp = con.newInstance(101,"zhangsan"); System.out.println(emp);
操作属性1.获取方法
getMethod() 类对象所表示的类的指定公共函数getMethods() 类对象所表示的类的所有公共函数getDeclaredMethod() 类对象所表示的类的指定任意函数 getDeclaredMethods() 类对象所表示的类的所有函数
2.调用方法
invoke(Object obj, Object... args) 在具有指定参数的指定对象上调用此 方法对象表示的基础方法
//获取所有的公共方法 包括静态 Method[] methods = employeeClass.getMethods(); Arrays.stream(methods).forEach(System.out::println); //获取指定的方法 Method method = employeeClass.getDeclaredMethod("testPrivate"); System.out.println(method); method.setAccessible(true); //调用方法 无参返回null System.out.println(method.invoke(emp)); //静态方法 存在返回值 可以跟随对象调用|可以跟随类名调用 for (Method m : methods) { if("testStatic".equals(m.getName())){ //指定通过emp对象调用 //System.out.println(m.invoke(emp,-1000)); //null 通过类名调用 System.out.println(m.invoke(null,-1000)); } }
2.注解1.获取属性
getField() 类对象所表示的类的指定公共属性getFields() 类对象所表示的类的所有公共属性getDeclaredField() 类对象所表示的类的指定任意属性 getDeclaredFields() 类对象所表示的类的所有属性
2.获取属性值
get(Object obj) 返回指定对象上此 字段表示的字段的值
3.设置属性值
set(Object obj, Object value) 将指定对象参数上此 字段对象表示的字段设置为指定的新值
//获取所有公共的 Field[] fileds = cls.getFields(); System.out.println(Arrays.toString(fileds)); //根据属性名获取指定的属性 Field filed = cls.getDeclaredField("name"); System.out.println(filed); //忽略权限 filed.setAccessible(true); filed.set(emp,"lisi"); System.out.println(filed.get(emp));
内置注解注解是jdk1.5的新特性
作用 :
1.注释,解释的作用
2.标志检查的作用 @InterfaceFuntion 检查是不是一个函数式接口 也能表明这是一个函数式接口
3.添加注解的时候可以通过配置传递参数,运行期间可以通过反射获取到配置的数据,程序中进行使用
4.注解可以存在与Class文件中
5.注解大量的代替了配置文件的存在
元注解@Oveeide 限定重写父类方法
@Deprecated 标记已过时
@SuppressWarnings 抑制警告 @SuppressWarnings("all") 所有画横线的
@FunctionalInterface 函数式接口
自定义注解原注解 : 注解注解的注解
@Target 用于描述注解的使用范围(即:被描述的注解可以用在什么地方)
@Retention 表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有)
@documented 表示使用该注解的元素应被javadoc或类似工具文档化
@Inherited 表示一个注解类型会被自动继承。 //子类没有的注解会从父类寻找
@Target和@Retention1.通过@interface自定义注解类型
2.自定义的注解类型默认实现java.lang.annotation Annotation接口
3.自定义的注解类型不能显示的继承其他父类,实现其他接口
4.注解类中可以定义注解类型的字段,特数的定义方法,需要字段名后面添加() --> 修饰符 类型 字段名();
5.如果注解类型中只有一个字段,建议这个字段定义为value,附值的时候可以直接赋值
6.注解类型中的字段的数据类型,只能为一下几种类型:基本数据类型,String,Annotation,枚举类型,或者这几种类型的数组
7.字段的修饰符只能为public|default
8.通过default关键字为字段定义默认值
@Target中的属性 ElementType
1.CONSTRUCTOR 描述构造器
2.FIELD:用于描述域
3.LOCAL_VARIABLE:用于描述局部变量
4.METHOD: 用于描述方法 5.PACKAGE: 用于描述包 6. PARAMETER: 用于描述参数 7.TYPE: 用于描述类、接口 ( 包括注解类型 ) 或 enum 声明
@Rentention RetentionPolicy
1.SOURCE: 在源文件中有效(即源文件保留)
2.CLASS:在class文件中有效(即class保留)在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife)
3.RUNTIME:在运行时有效(即运行时保留) //注解处理器可以通过反射,获得该注解的属性值,从而处理一些运行时的逻辑处理
class Defined{
@MyAnnotation(value="zhangsan",j=10)
String name;
}
@Target(ElementType.FIELD)
//在声明在运行期间 可以进行数值的绑定
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
//value 默认是他 如果不是需要属性=""
String value();
int j() default -1;
}



