1.注解
1.1 概念
注解(Annotation),也叫元数据,标签,注释。注解叫注释的时候,容易和java的代码注释混淆,一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释
1.2 作用
- 编写文档
- 代码分析
- 编译检查
1.3 注解的三要素
- 需要有一个注解;(有一个标签)
- 使用这个注解(这个注解贴在什么地方);
- 第三方程序为注解实现功能
1.4 JDK四大内置注解
- @Override注解用于标识方法重写,例如当前类中重写tostring()方法
- @Deprecated注解用于标识方法已过时
- @SuppressWarings注解用于抑制编译器警告,直白的讲就是消除Eclipse上那条黄色警告线,但编译器里关于这条警告的信息还在。
- @SafeVarargs抑制堆污染警告(单独警告),直白的讲就是使用泛型和可变参数搭配使用将会产生的编译器警告,可以使用@SuppressWarnings消除警告
1.5 元注解
元注解的作用就是用于定义其他注解,是由JAVA为我们提供的,不能更改,从JAVA5.0开始一共为我们提供了四个元注解。
-
@Target作用
用于描述注解的使用范围,也就是说使用了@Target去定义一个注解,那么可以决定定义好的注解能用在什么地方
-
@Documented作用
使用@Documented定义后的注解,在该注解使用后,如果导出API文档,会将该注解相关的信息可以被例如javadoc此类的工具文档化。
-
@Retention作用
用于描述注解的生命周期,也就是说这个注解在什么范围内有效,注解的生命周期和三个阶段有关:源代码阶段、CLASS文件中有效、运行时有效,故其取值也就三个值,分别代表着三个阶段
-
@Inherited作用
使用@Inherited定义的注解具备继承性
假设一个注解在定义时,使用了@Inherited,然后该注解在一个类上使用,如果这个类有子类,那么通过反射我们可以从类的子类上获取到同样的注解
1.6 自定义注解
语法:
元注解
public @interface 注解名{
类型 属性名() default 默认值; //default可以不写
}
2.反射
2.1 概念
在运行时期,动态地去获取类中的信息(类的信息,方法信息,构造器信息,字段等信息);
2.2 作用
-
增加程序的灵活性,避免将程序写死到代码里(解除硬编码的问题);
-
Java的反射机制它知道类的基本结构,可以动态的去获取类这样的结构的结构;
-
可以让程序员在不知道其它程序员会有什么类的时候就编写完成自己的代码;
-
反射的优点:灵活,功能强大(可以拿到私有的…);
反射的缺点:破坏封装,影响性能
2.3 Class实例的获得方式
-
类的字节码文件对象 一个类的字节码文件对象只有一个
a. 类名.class
b. 对象名.getClass();
c. Class.forName(全限定名); 全限定名:包名+类名 框架底层用的最多的是这种
-
接口的字节码文件对象
a.接口名称.class
b.Class.forName(全限定名);
-
数组的字节码文件对象
a.数组对象.getClass();
b.数组类型.class -
基本数据类型的字节码文件对象
a.基本数据类型.class
b.包装数据类型.type
2.4 反射的运用
2.4.1 获得构造方法
//获取公有的无参构造方法
Person person1 = p.newInstance();
person1.setName("hh");
person1.setAge(22);
System.out.println(person1);
//获取公有的有参构造方法
Constructor<Person> constructor = p.getConstructor(String.class);
Person person2 = constructor.newInstance("hahh");
System.out.println(person2);
2.4.2 获得方法
//获取私有方法
Method method = p.getDeclaredMethod("fly", String.class);
method.setAccessible(true);
method.invoke(new Person(), "我");
//获取公有方法
Method method = p.getMethod("setName", String.class);
Person person = new Person();
method.invoke(person, "hahhahha");
System.out.println(person);
2.4.3 获得字段
//获取私有字段
Field field = p.getDeclaredField("name");
field.setAccessible(true);
Person person = new Person();
field.set(person, "haha");
System.out.println(person);
//获取公有字段
Field field2 = p.getField("sex");
Person person = new Person();
field2.set(person, "男");
System.out.println(person);
2.4.4 获得注解
//获取注解
VIP vip = p.getAnnotation(VIP.class);
int level = vip.level();
System.out.println(level);
String name = vip.name();
System.out.println(name);