详解 注解
注解
基本知识点:
概念:
注解(Annotation),也叫元数据
一种代码级别的说明
它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次
它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,
用来对这些元素进行说明,注释
格式:
@interface 注解名{}
作用:
- 编译检查
- 替代配置文件
- 定义注解(元注解:注解上的注解)
那么,其实我们对于注解也不是很陌生,在我们之前的学习中,经常会见过如下3个注解:
3个常见注解:
- @Override:
声明该方法是从分类上继承过来的,执行编译期的检查- @SuppressWarnings:
抑制警告
值有好多,只需要知道一个 all (即:抑制所有的警告)- @Deprecated:
声明 该方法不赞成使用
在我们后续的框架学习的过程中,会见到框架中的好多自定义注解,
那么,现在,本人就来讲解一下 自定义注解:
自定义注解:
自定义注解其实也没什么困难的,我们只需要搞明白两点就好 —— 属性 和 元注解:
注解的属性:
概念:
注解本质就是一个接口,
可以用javap 这个命令反编译一下 注解的字节码文件
接口中可以有常量和抽象方法
抽象方法在注解中就称之为注解属性
注解属性所支持的类型:
- 八大基本类型(byte、boolean、char、short、int、float、long、double)
- String
- Class
- Annotation
- Enum:枚举
- 以上类型对应的一维数组
注意:
一旦注解有属性了,
使用注解的时候必须赋值(除非这个注解属性有默认值)
格式:
public @interface 注解名 {
属性类型1 属性名1(); //注解的属性,前面的public abstract可以省略
属性类型2 属性名2() default 属性的默认值; //使用时可以不赋值
...
}
那么,现在本人就来展示下自定义注解的属性:
public @interface MyAnnotation {
public abstract String name(); //注解的属性,前面的public abstract 可以省略
int age(); //前面的数据类型,不是所有类型都支持
}
那么,自定义注解 仅有属性是不够的,
还需要元注解来约束它的使用范围及运行时期:
元注解:
元注解主要分为4个:
- @Retention注解:
约束普通注解的运行时期- @Target注解
约束普通注解的使用范围- @Documented注解:
生成说明文档,添加类的解释- @Inherited注解:
允许子类继承父类中的注解
在本人上面的描述中,我们可以知道:
对于元注解,在我们自定义注解时,一般只应用前两个,
即:@Retention注解 和 @Target注解
(但是这并不代表别人不会用后两个元注解)
那么,本人在这里,就来讲解下 @Retention注解 和 @Target注解 的取值:
取值:
- @Retention注解:
SOURCE —— 源码状态运行
CLASS —— 编译类文件时运行
RUNTIME —— 运行时运行
(一般我们取值为RUNTIME,以保证注解最长时间内有效)- @Target注解:
TYPE —— 给类(型)注解
FIELD —— 给字段注解,不要忘了,字段可以是对象
METHOD —— 给方法注解
PARAMETER —— 给参数注解
CONSTRUCTOR —— 给构造方法注解
LOCAL_VARIABLE —— 给局部变量注解
ANNOTATION_TYPE —— 给注解注解
PACKAGE —— 给包注解
那么,现在本人来展示下自定义注解:
package edu.youzg.about_annotation.core;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({ METHOD, PARAMETER })
public @interface MyAnnotation {
public abstract String name();
int age() default 666;
}
那么,现在本人就来展示下自定义注解的使用:
package edu.youzg.about_annotation.core;
import java.lang.reflect.Method;
public class Demo {
@MyAnnotation(name="youzg")
public static void doSomeThing() throws NoSuchMethodException, SecurityException {
Class<?> klass = Demo.class;
Method method = klass.getMethod("doSomeThing");
MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);
String name = annotation.name();
int age = annotation.age();
System.out.println(name + age);
}
public static void main(String[] args) {
try {
doSomeThing();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
现在,本人来展示下运行结果:
那么,现在本人来通过注解来改动下之前本人讲解的JDBC工具:
小案例 —— JDBC工具:
首先,本人先来给出一个注解:
package edu.youzg.about_annotation.core;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target({ METHOD})
public @interface JDBCAnnotation {
String driverClass() default "com.mysql.jdbc.Driver";
String url() default "jdbc:mysql://localhost:3306/dbstudy";
String user() default "root";
String password() default "123456";
}
现在,本人来给出注解配置的JDBC工具:
package edu.youzg.about_annotation.core;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JDBCUtils {
@JDBCAnnotation(password = "123456")
public static Connection getConnection() throws NoSuchMethodException, ClassNotFoundException, SQLException {
//获取该类的字节码文件对象
Class klass= JDBCUtils.class;
//获取方法对象
Method m = klass.getMethod("getConnection");
//判断该方法上是否有注解,如果有获取到注解
boolean b = m.isAnnotationPresent(JDBCAnnotation.class);//参数:是注解的Class类型
if (b) { //如果方法上有注解,获取注解,并拿到注解的属性值
JDBCAnnotation annotation = m.getAnnotation(JDBCAnnotation.class);
//获取注解属性的值
String driverClass = annotation.driverClass();
String url = annotation.url();
String user = annotation.user();
String password = annotation.password();
Class.forName(driverClass);
return DriverManager.getConnection(url,user,password);
}
return null;
}
}
现在,本人来给出一个测试类:
package edu.youzg.about_annotation.core;
import java.sql.Connection;
import java.sql.SQLException;
public class Demo {
public static void main(String[] args) throws NoSuchMethodException, ClassNotFoundException, SQLException {
Connection connection = JDBCUtils.getConnection();
System.out.println(connection);
}
}
那么,本人现在来展示下运行结果: