01_注解介绍
A.定义
- 注解annotation是Java语言中用于描述类,成员变量,构造方法,成员方法,方法参数及包声明的
特殊的修饰符.用于描述这些信息的元数据.例如@Override用于描述一个方法是在子类中重
写的方法
B.特点
- 是JDK5.0之后引入的特性.注解是以”@注解名”在代码中存在的
C.作用
- 跟踪代码依赖性
- 执行编译时格式检查
- 代替已有的配置文件
02_JDK内置注解
JDK内置注解,JDK1.5之后内置了三个系统注解
A.@Override
- 标记在成员方法上,用于标识当前方法是重写父类方法,编译器在对该方法进行编译时会检查是否符合重写规则,如果不符合,编译报错
B.@Deprecated
- 用于标记当前类、成员变量、成员方法或者构造方法过时如果开发者调用了被标记为过时的
方法,编译器在编译期进行警告
C.@SuppressWarnings
- 可放置在类和方法上,该注解的作用是阻止编译器发出某些警告信息,该注解为单值注解,只有一个value参数,该参数为字符串数组类型,参数值常用的有:
1、unchecked 未检查的转化,如集合没有指定类型还添加元素
2、unused 未使用的变量
3、resource 有泛型未指定类型
4、path 在类路径,原文件路径中有不存在的路径
5、deprecation 使用了某些不赞成使用的类和方法
6、fallthrough switch语句执行到底没有break关键字
7、rawtypes 没有写泛型,比如: List list = new ArrayList();
8、all 全部类型的警告
03_注解分类
根据注解的参数个数分为三类:
标记注解:
没有参数的注解,仅用自身的存在与否为程序提供信息,如@Override注解,该注解没有参数,用于表示当前方法为重写方法
单值注解:
只有一个参数的注解,如果该参数的名字为value,那么可以省略参数名,如
@SuppressWarnings(“all”),可以简写为@SuppressWarnings(“all”).
完整注解:
有多个参数的注解
04_元注解
A.自定义注解:
- 格式 @interface 注解名
B.定义
- 用户负责描述其他注解的注解
- 在自定义注解时,需要指定注解可以应用在哪些位置(如:方法,参数,类上等)以及自定义注解的停留策略等信息,那么就可以通过元注解去描述这些信息了.
C.分类
JDK1.5中定义了四个元注解,常用的两个注解,如下:
- @Target
- 作用: 用于描述当前定义的注解可以应用的范围该注解仅有一个属性value,该属性值为ElementType数组类型ElementType为枚举类型,枚举值和作用说明如下:
- TYPE 当前定义的注解可以应用在类、接口和枚举的类型定义部分
- FILED 当前定义的注解可以应用在成员变量上
- METHOD 当前定义的注解可以应用在成员方法上
- PARAMETER 当前定义的注解可以应用在方法参数上
- CONSTRUCTOR 当前定义的注解可以应用在构造方法上
- LOCAL_VARIABLE 当前定义的注解可以应用在局部变量上
- ANNOTATION_TYPE 当前定义的注解可以应用在注解类型上
- PACKAGE 当前定义的注解可以应用在包定义语句上
- @Retention
作用: 用于描述当前定义的注解可以保留的时间长短该注解只有一个value参数,参数类型为RetentionPolicy.RetentionPolicy类型为枚举类型
- SOURCE 当前定义的注解仅仅停留在源码中,编译时即除去
- CLASS 当前定义的注解保留到编译后的字节码中,运行时无法获取注解信息
- RUNTIME 当前定义的注解可以保留到运行时,通过反射机制可以获取注解信息
05_自定义注解案例
A.需求:
- 可以使添加有自定义注解的方法执行
- 在类的某些方法上添加@MyTest的注解.
- 可以使加有@MyTest的注解的方法执行.
B.实现
public class MyTestCore {
public static void main(String[] args) throws ClassNotFoundException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException,
InstantiationException {
/**
* 获得类的Class对象.
* 通过Class找出里面的所有的方法.
* 遍历所有的方法.
* 需要在每个方法上查找是否有@MyTest注解.
* * 如果有该注解:
* * 执行该方法.
*/
// 获得类的Class对象.
Class clazz = Class.forName("cn.aaa.annotation.AnnotationDemo1");
// 获得类中的所有的方法.
Method[] methods = clazz.getMethods();
// 遍历所有的方法:
for (Method method : methods) {
// 判断方法上是否有某个注解:
boolean flag = method.isAnnotationPresent(MyTest.class);
// System.out.println(method.getName()+" "+flag);
if (flag == true) {
// 执行该方法:
method.invoke(clazz.newInstance(), null);
}
}
}
}
06_自定义注解之改变JDBC工具类
A.自定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
public @interface JDBCInfo {
String driverClass() default "com.mysql.jdbc.Driver";
String url() default "jdbc:mysql:///aaa";
String username() default "root";
String password() default "123456";
}
B.定义JDBC的工具类:
public class JDBCUtils {
/**
* 工具类中获得数据库连接的方法:
*
* @return
* @throws ClassNotFoundException
*/
@JDBCInfo(password = "1234")
public static Connection getConnection() throws Exception {
/**
* 获得当前类上的getConnection方法.
* 获得该方法上的@JDBCInfo这个注解.
* 获得这个注解中的属性的值.
* 使用这些值为下面参数设置值.
*/
// 获得JDBCUtils的类的Class对象.
Class clazz = JDBCUtils.class;
// 获得getConnection方法:
Method method = clazz.getMethod("getConnection", null);
// 获得方法上的注解:
JDBCInfo jdbcInfo = method.getAnnotation(JDBCInfo.class);
// 获得注解中的属性的值:
String driverClass = jdbcInfo.driverClass();
String url = jdbcInfo.url();
String username = jdbcInfo.username();
String password = jdbcInfo.password();
// 加载驱动:
Class.forName(driverClass);
// 获得连接:
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
}
}