上一讲,我介绍了 Java 是如何通过反射动态创建与使用对象的。本讲将介绍 Java 是如何通过反射操作注解的?
1、通过反射获取运行时类的完整结构
我们可以通过反射获取运行时类的完整结构,主要包括:字段(Field)、方法(Method)、构造器(Constructor)、父类(Superclass)、接口(Interface)、注解(Annotation)等。
如:
import java.lang.annotation.ElementType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* 获取运行时类的完整结构
*/
public class test {
public static void main(String[] args) throws ClassNotFoundException {
Class c1 = Class.forName("java.lang.String");//反射获取String类的Class对象
System.out.println("全类名:" + c1.getName());//获取全类名
System.out.println("类的简单名称:" + c1.getSimpleName());//获取类的简单名称
System.out.println("---------------------------");
//获取类的public属性
Field[] fields = c1.getFields();
for (Field field : fields ) {
System.out.println("类的public属性:" + field);
}
System.out.println("---------------------------");
//获取类的全部属性
Field[] declaredFields = c1.getDeclaredFields();
for (Field field : declaredFields ) {
System.out.println("类的全部属性:" + field);
}
System.out.println("---------------------------");
//获取本类及父类的public方法
Method[] methods = c1.getMethods();
for (Method method : methods ) {
System.out.println("本类及父类的public方法:" + method);
}
System.out.println("---------------------------");
//获取本类的全部方法
Method[] declaredMethods = c1.getDeclaredMethods();
for (Method method : declaredMethods ) {
System.out.println("本类的全部方法:" + method);
}
System.out.println("---------------------------");
//获取类的public构造器
Constructor[] constructors = c1.getConstructors();
for (Constructor constructor : constructors ) {
System.out.println("类的public构造器:" + constructor);
}
System.out.println("---------------------------");
//获取类的所有构造器
Constructor[] declaredConstructors = c1.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors ) {
System.out.println("类的所有构造器:" + declaredConstructor);
}
}
}
运行结果如下图所示(部分):
2、通过反射操作注解
下面我们将通过练习ORM,学习如何通过反射操作注解。
2.1、什么是ORM
ORM,即:Object-Relational Mapping(对象关系映射)。它的作用是在关系型数据库和业务实体对象之间作一个映射。
其中:
-
类和表结构对应;
-
属性和字段对应;
-
对象和记录对应。
常用的 Java ORM 框架有 Hibernate 和 Mybatis。
2.2、利用注解与反射完成类和表结构的映射关系
例:利用注解与反射完成Student
类和db_student
表结构(字段分别为:db_id、db_age、db_name
)的映射关系。
import java.lang.annotation.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 反射操作注解
*/
public class test {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
Class c1 = Class.forName("Student");//通过反射获取Student类的Class对象
//通过反射获取Student类的注解信息
Annotation[] annotations = c1.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
System.out.println("-----------------------");
//通过反射获取Student类的注解的value值
TableName tableName = (TableName) c1.getAnnotation(TableName.class);
String value = tableName.value();
System.out.println(value);
System.out.println("-----------------------");
//通过反射获取Student类中name属性的注解信息
Field name = c1.getDeclaredField("name");
Annotation[] annotations1 = name.getAnnotations();
for (Annotation annotation : annotations1) {
System.out.println(annotation);
}
System.out.println("-----------------------");
//通过反射获取Student类中name属性的注解的值
FieldName annotation = name.getAnnotation(FieldName.class);
System.out.println(annotation.columnName());
System.out.println(annotation.type());
System.out.println(annotation.length());
}
}
//实体类
@TableName("db_student")//使用自定义类名的注解,将类名和数据库表名对应
class Student{
@FieldName(columnName = "db_id",type = "int",length = 10)//使用自定义属性的注解,将类的id属性和数据库的db_id字段对应
private int id;
@FieldName(columnName = "db_age",type = "int",length = 10)//使用自定义属性的注解,将类的age属性和数据库的db_age字段对应
private int age;
@FieldName(columnName = "db_name",type = "varchar",length = 3)//使用自定义属性的注解,将类的name属性和数据库的db_name字段对应
private String name;
//无参构造器
public Student() {
}
//有参构造器
public Student(int id, int age, String name) {
this.id = id;
this.age = age;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", age=" + age +
", name='" + name + ''' +
'}';
}
}
//自定义类名的注解(用于类和表结构对应)
@Target(ElementType.TYPE)//适用于类
@Retention(RetentionPolicy.RUNTIME)//运行时有效
@interface TableName{
String value();//表名
}
//自定义属性的注解(用于属性和字段对应)
@Target(ElementType.FIELD)//适用于属性
@Retention(RetentionPolicy.RUNTIME)//运行时有效
@interface FieldName{
String columnName();//列名
String type();//数据类型
int length();//长度
}
关注 “阿汤笔迹” 微信公众号,获取更多学习笔记。
原文始发于微信公众号(阿汤笔迹):Java 究竟是如何通过反射操作注解的?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/236751.html