大学生小菜鸡学习记录,怕浪费佬们时间,可以现在划走
自定义注解相关基础知识
- 理解注解的本质
注解(Annotation)是一种为程序元素(类、方法、变量等)添加元数据的方式。它本身不直接影响逻辑,但可以被其他工具(如编译器、框架)读取并用于特定操作。
- 掌握自定义注解的创建
使用@interface关键字定义,其本质是一个自动继承了java.lang.annotation.Annotation的接口
定义时,你需要通过元注解来配置其行为,核心的元注解有两个:
@Target:指定注解可以应用在哪些地方,例如ElementType.METHOD表示注解只能用在方法上@Retention:指定注解的生命周期
- 掌握注解的解析(反射)
定义了RUNTIME级别的注解后,必须通过Java的反射机制来读取它并执行相应逻辑。这是注解发挥作用的桥梁。
实战一:模拟简易ORM框架
这个案例会模拟像Hibernate那样,用注解将Java对象与数据库表进行映射。
-
定义注解:创建两个注解。
java
// 表注解 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Table { String value(); // 用于存储表名 } // 列注解 @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Column { String value(); // 用于存储列名 } -
应用注解:在一个实体类上使用定义好的注解。
java
@Table("user") public class User { @Column("user_name") private String name; @Column("user_age") private Integer age; // 省略getter/setter } -
解析注解并生成SQL:编写一个工具方法,通过反射解析对象上的注解,拼接出SQL语句。
java
public static String generateInsertSQL(Object obj) throws Exception { Class<?> clazz = obj.getClass(); // 1. 获取@Table注解值作为表名 if (!clazz.isAnnotationPresent(Table.class)) { return null; } Table tableAnnotation = clazz.getAnnotation(Table.class); String tableName = tableAnnotation.value(); StringBuilder sql = new StringBuilder("INSERT INTO " + tableName + " ("); // 2. 遍历字段,获取@Column注解值作为列名,并通过getter获取值 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.isAnnotationPresent(Column.class)) { Column columnAnnotation = field.getAnnotation(Column.class); sql.append(columnAnnotation.value()).append(", "); } } // 3. 拼接完整的SQL字符串(此处需处理值的部分,代码已简化) sql.append(") VALUES (...);"); return sql.toString(); }
实战二:实现简单测试框架
这个案例模仿JUnit,通过注解来标记和运行测试方法,并自动捕获异常。
-
定义注解:创建一个
@Check注解,用于标记需要测试的方法。java
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface Check { } -
应用注解:在一个待测试的类中,用
@Check标记要测试的方法。java
public class Calculator { @Check public void add() { System.out.println("1 + 0 = " + (1 + 0)); } @Check public void div() { System.out.println("1 / 0 = " + (1 / 0)); } // 这里会抛出算术异常 } -
解析注解并运行测试:编写测试运行器,检查所有带
@Check注解的方法,用反射调用它们并记录异常。java
public class TestRunner { public static void main(String[] args) throws Exception { Calculator calc = new Calculator(); Class<?> clazz = calc.getClass(); Method[] methods = clazz.getMethods(); for (Method method : methods) { // 判断方法是否有@Check注解 if (method.isAnnotationPresent(Check.class)) { try { method.invoke(calc); // 执行方法 System.out.println(method.getName() + ": 测试通过"); } catch (Exception e) { System.out.println(method.getName() + ": 发生异常 - " + e.getCause().getMessage()); } } } } }