注解
一、jdk中自带三个注解:
1.@Override 是给编译器使用,用于描述当前的方法是一个重写的方法。
注意:在jdk1.5与jdk1.6中有区别 jdk1.5中@Override它只能描述继承中的重写.jdk1.6中@Override它不仅能描述继承中的重写,还可以描述实现中的重写.
2.@Deprecated 它是用于描述方法过时。
3.@SuppressWarnings 去除程序中的警告信息
unused 变量未使用 deprecation 使用了不赞成使用的类或方法时的警告 unchecked 执行了未检查的转换时的警告,例如当使用集合时没有用泛型 (Generics) 来指定集合保存的类型。 fallthrough 当 Switch 程序块直接通往下一种情况而没有 Break 时的警告。 path 在类路径、源文件路径等中有不存在的路径时的警告。? serial 当在可序列化的类上缺少 serialVersionUID 定义时的警告。? finally 任何 finally 子句不能正常完成时的警告。 all 关于以上所有情况的警告。
二、定义注解
1.定义注解 @interface 名称 就定义了一个注解,要想使用 在类,方法,属性上直接 @名称.
问题:@interface 名称,是声明了一个注解,它的本质是什么?
@interface MyAnnotation{} 它的本质就是
import java.lang.annotation.Annotation; interface MyAnnotation extends Annotation{}
注解的本质就是一个接口,它继承了Annotation接口。所有的注解都实现了这个接口,但是,不能手动实现。注解是jdk1.5的新特性.
2.注解中的成员
1.可以有属性 注解中可以有属性,但是基本不使用。
2.可以有方法 我们一般管它叫做注解中的属性。
2.1关于注解中的属性的类型问题
它的类型只能是以下几种: 1.基本类型 整型:byte short int long 浮点:float double 字符:char 逻辑:boolean 2.String 3.Class 4.enum 5.Annotation 6.以上类型的一维数组。
2.2 关于注解中有属性,使用的问题
如果一个注解中有属性,并且属性没有默认值,那么我们在使用注解时,必须给注解的属性赋值. 关于属性赋值方式: 1.默认值问题 String st() default "abc"; 2.如果是单值 注解(属性名称=值) 例如:@MyAnnotation3(i=1) 3.如果是数组 3.1.如果只赋一个值 注解(属性名称=值) 例如:@MyAnnotation3(i=1) 3.2.如果要赋多个值 注解(属性名称={值1,值2,...}) 例如:@MyAnnotation3(i={1,2,3}) 4.关于属性名称value问题 可以省略属性名称 例如 @MyAnnotation3("hello");如果value属性是一个数组:@MyAnnotation3({"a","b"})如果注解中有value属性,还有其它属性:那么value属性名称不能在省略.
3.元注解
1.@Retention 作用:是指定注解给谁使用. 它的属性值只能是以下三个 RetentionPolicy.SOURCE 给编译器使用 使用后抛弃 RetentionPolicy.CLASS 给解析器使用。当jvm加载完成后,就抛弃. RetentionPolicy.RUNTIME jvm加载完成后,还存在。开发人员可以通过反射来获取注解相关信息. 2.@Target 作用:就是定义注解在什么位置使用 3.@Documented 作用:是通过javadoc生成的文档中是否抽取注解描述. 4.@Inherited 作用:是描述当前注解是否具有继承性
三、实例
3.1 使用注解替代配置文件
1- 使用注解前: 配置文件:Bank.properties 内容:money=50000
public class Bank { // name1向name2转账money元---使用配置文件完成 public void account1(String name1, String name2, int money) { if (money > GlobalField.MONEY) { throw new RuntimeException("最大转账金额为:5000元"); } System.out.println(name1 + "向" + name2 + "转账:" + money + "元"); } }
2- 使用注解后: 没有配置文件,取而代之的是一个注解类 BankInfo.java
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface BankInfo { int maxMoney(); }
然后,使用该注解:
package cn.itcast.annotation.demo1; import java.lang.reflect.Method; //银行最大转账金额5000 public class Bank { // name1向name2转账money元--使用注解 @BankInfo(maxMoney = 100000) public void account(String name1, String name2, int money) throws NoSuchMethodException, SecurityException { // 1.获取当前方法的Method对象。 // 1.1 获取当前类的Class对象 Class clazz = this.getClass(); // 1.2 获取当前方法的Method对象. Method method = clazz.getDeclaredMethod("account", String.class, String.class, int.class); boolean flag = method.isAnnotationPresent(BankInfo.class); // 判断当前方法上是否有BankInfo这个注解. if (flag) { // 2.在Method类中有一个 getAnnotation(Class annotationClass),可以获取一个注解对象. BankInfo bif = method.getAnnotation(BankInfo.class); // 3.通过注解对象来调用其属性. int maxMoney = bif.maxMoney(); if (money > maxMoney) { throw new RuntimeException("最大转账金额为:" + maxMoney + "元"); } System.out.println(name1 + "向" + name2 + "转账:" + money + "元"); } } }
配置文件的出现,它的主要目的就是解耦合。但是随着现在开发程序越来越庞大,配置文件的缺点就出现了,配置文件内容越来越庞大,就不利于我们开发与阅读.
这时就出现了注解,因为注解可以直接写在代码上,并且,通过注解也可以解耦合。
3.2 使用注解连接JDBC
JdbcInfo.java
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface JdbcInfo { String driverClassName(); String url(); String username(); String password(); }
JdbcUtils.java
import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.util.Arrays; public class JdbcUtils { public static Connection getConnection() throws Exception { String driverClassName = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql:///day24"; String username = "root"; String password = "abc"; // 1.加载驱动 Class.forName(driverClassName); // 2.获取连接 Connection con = DriverManager.getConnection(url, username, password); return con; } @JdbcInfo(driverClassName = "com.mysql.jdbc.Driver", url = "jdbc:mysql:///day24", username = "root", password = "abc") public static Connection getConnectionByAnnotation(String[] args) throws Exception { System.out.println(Arrays.toString(args)); // 得到当前方法上的注解JdbcInfo Method method = JdbcUtils.class .getDeclaredMethod("getConnectionByAnnotation",String[].class); JdbcInfo jif = method.getAnnotation(JdbcInfo.class); String driverClassName = jif.driverClassName(); String url = jif.url(); String username = jif.username(); String password = jif.password(); // 1.加载驱动 Class.forName(driverClassName); // 2.获取连接 Connection con = DriverManager.getConnection(url, username, password); return con; } public static void main(String[] args) throws Exception { System.out.println(getConnectionByAnnotation(new String[]{"abc"})); } }