注解

一、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 关于以上所有情况的警告。
View Code

  二、定义注解

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.以上类型的一维数组。
View Code

   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属性名称不能在省略.
View Code

3.元注解  

1.@Retention 作用:是指定注解给谁使用. 它的属性值只能是以下三个
RetentionPolicy.SOURCE  给编译器使用  使用后抛弃
RetentionPolicy.CLASS   给解析器使用。当jvm加载完成后,就抛弃.                          
RetentionPolicy.RUNTIME    jvm加载完成后,还存在。开发人员可以通过反射来获取注解相关信息.                            
2.@Target 作用:就是定义注解在什么位置使用
3.@Documented 作用:是通过javadoc生成的文档中是否抽取注解描述.
4.@Inherited  作用:是描述当前注解是否具有继承性
View Code

 三、实例 

 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 + "元");
    }

}
View Code

     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();
}
View Code

     然后,使用该注解:

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 + "元");
        }
    }
}
View Code

配置文件的出现,它的主要目的就是解耦合。但是随着现在开发程序越来越庞大,配置文件的缺点就出现了,配置文件内容越来越庞大,就不利于我们开发与阅读.
这时就出现了注解,因为注解可以直接写在代码上,并且,通过注解也可以解耦合。

 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();
}
View Code

    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"}));
    }
}
View Code

 

     

posted @ 2017-06-27 16:59  ABO-阿博  阅读(137)  评论(0编辑  收藏  举报