一、注解
1 、注解的定义
- 不是程序本身,可以对程序做出解释
- 可以被其他程序读取
- 以@开头,可以附在加载package,class等上面,相当于给他们添加了额外的辅助信息,可以通过反射访问这些元数据
2、内置注解
-
@Override
-
@Deprecated
-
@SuppressWarning
3、元注解
- 元注解的作用就是负责解释其他注解,java定义了4个标准的meta-annotation类型,他们提供对其他annotation类型做说明。
- @Target:注解的使用范围(方法、类等)
- @Retention:需要在什么级别保存该注释信息,用来描述注解的生命周期(source < class < runtime)
- @Documented:该注解包含在javadoc中
- @Inherited:说明子类可以继承父类中的该注解
4、自定义注解
- @interface用来声明一个注解
- 其中的每一个方法实际上声明了一个配置参数
- 方法的名称就是参数的名称
- 返回值类型是参数的类型
- 可以通过default来声明参数的默认值
- 如果只有一个参数,命名为value,因为只有value命名,使用注解时,参数名可以省略
- 注解元素必须要有值
import java.lang.annotation.*;
public class MyAnnotation {
@FirstAnnotation("")
public void test(String[] args) {
}
@SecondAnnotation(likes = {"apple","banana"})
public void test2(String[] args) {
}
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface FirstAnnotation {
String value();
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@interface SecondAnnotation {
int id() default 0;
String name() default "";
String[] likes();
}
二、反射
1、定义
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
反射的在实际中的主要应用是:通过反射获取注解对象,各种框架的底层实现都是如此
2、获得class
- Class本身也是一个类
- Class对象由系统创建
- 一个加载的类在JVM中只会一个Class实例
- 一个Class对象对应的是一个加载到JVM中的.class文件
- 每个类的实例都会记得自己是由哪个Class实例生成
- 通过Class可以完整的得到一个类中的所有被加载的结构
(1)Class.forName 静态方法。
前提:知道该类的全路径名
Class clz = Class.forName("java.lang.String");
(2)使用 .class 方法(最安全可靠,程序性能最高)
前提:已知具体的类
Class clz = String.class;
(3)使用类对象的 getClass() 方法。
前提:存在实例对象
String str = new String("Hello");
Class clz = str.getClass();
(4).Type
说明:只适用于内置基本数据类型
Class<Integer> type = Integer.TYPE;
package study;
public class testGetClass {
public static void main(String[] args) throws ClassNotFoundException {
Person person = new Person();
Class c1 = person.getClass();
Class c2 = Class.forName("study.Person");
Class<Person> c3 = Person.class;
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
Class<Integer> type = Integer.TYPE;
System.out.println(type.hashCode());
}
}
class Person {
private int id;
private String name;
public Person() {
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
3、创建对象
-
newInstance()
调用了无参构造方法 -
getConstructor.newInstance
有参构造方法 -
invoke
操作属性,操作私有方法和属性时,需要设置method.setAccessible(true)
,method.setAccessible(true)
可以加快反射的速度
package test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestReflect {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class c = Class.forName("test.Person");
//无参构造
Person object = (Person) c.newInstance();
System.out.println(object);
//有参构造
object = (Person) c.getConstructor(int.class, String.class).newInstance(1,"阿萨德");
System.out.println(object);
//操作方法
Method method = c.getDeclaredMethod("setName", String.class);
method.setAccessible(true);
method.invoke(object,"小明");
System.out.println(object);
}
}
class Person {
private int id;
private String name;
public Person() {
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
4、反射注解
获取类注解 [class].getAnnotation([注解.class])
获取方法注解[method].getAnnotation([注解.class])
事例:模拟MybatisPlus实体表映射
package test;
import java.lang.annotation.*;
**import java.lang.reflect.Field;**
/**
* @author huahua
* @description 测试类
* @date 2020/12/24 14:10
**/
public class ReflectAnnotation {
public static void main(String[] args) throws ClassNotFoundException {
//获取类注解
Class c = Student.class;
Table_self annotation = (Table_self) c.getAnnotation(Table_self.class);
System.out.println(annotation.value());
//获取方法注解
Field[] declaredFields = c.getDeclaredFields();
for (Field declaredField : declaredFields) {
Field_self fieldAnnotation = declaredField.getAnnotation(Field_self.class);
System.out.println(fieldAnnotation);
}
}
}
/**
* @author huahua
* @description 自定义表名注解
* @date 2020/12/24 14:08
**/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Table_self {
String value();
}
/**
* @author huahua
* @description 自定义属性注解
* @date 2020/12/24 14:19
**/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Field_self {
//字段名
String name();
//字段类型
String type();
//字段长度
int length();
}
/**
* @author huahua
* @description 实体类
* @date 2020/12/24 14:08
**/
@Table_self("student")
class Student {
@Field_self(name = "id", type = "int", length = 10)
private int id;
@Field_self(name = "name", type = "varchar", length = 10)
private String name;
public Student() {
}
public Student(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}