JAVA -注解

JAVA SE-注解

一个专心致志思索的人并不是在虚度光阴。虽然有些劳动是有形的,但也有一种劳动是无形的。 —— 雨果

什么是注解?注解有什么用?
  • 注解就是 @xxx 这样的东西就是注解.
    • 注释:给程序员看的.
    • 注解:给程序看。
    • 使用注解的目的: 其实将来使用注解目的就是为了代替传统配置文件.

@Override

public class Demo1 implements Person {

    @Override
    //向编译器描述,该方法是被重写的.
    //帮你检查,被注解修饰方法是否是被重写的,如果不是编译报错!
    //@Override 1.5版本只接受继承性质的重写.  1.6版本也接受实现接口性质的重写
    public void eat() {

    }
    //@Override
    public void eat2() {

    }

}

@Deprecated

public class Demo2 {
    @Deprecated
    //该注解告诉编译器,被修饰的方法是过时方法
    public static void show(){
        System.out.println("hello world!");
    }

    public static void main(String[] args) {
        Demo2.show();
    }
}

@SuppressWarnings

public class Demo3 {

    //@SuppressWarnings({"null","rawtypes", "unchecked"})
    @SuppressWarnings("all")
    //告诉编译器,不要检查什么错误!
    //如果填写all,那么什么错误都不检查.
    public static void main(String[] args) {
        String str = null;
        str.substring(0);

        //@SuppressWarnings("unused")
        String str2 = null;

        List list = new ArrayList();
        list.add("abc");
    }
}
如何自定义一个注解?
public @interface MyAnnotation {

    //声明属性=> 抽象方法


    //声明一个名为name的属性  类型是String
    String value();


    //如果注解中,必填属性只有一个. 这个属性的名字是"value".那么在赋值时不需要加属性的键.
}
    分析一下注解的本质:
        将其.class文件找到,反编译.

        @interface MyAnnoation{}

        反编译后的结果
        interface MyAnnotation  extends Annotation
        {
        }

       结论:注解本质上就是一个接口。它扩展了java.lang.annotation.Annotation接口;

       在java中所有注解都是Annotation接口的子接口。

      注解也是jdk1.5的一个新特性.
注解的属性
注解的成员

        注解本质上就是一个接口,那么它也可以有属性和方法。
        但是接口中的属性是  static final的,在注解中注解没有什么意义。

        在开发中注解中经常存在的是方法。而在注解中叫做注解的属性.

    注解的属性的类型:
        1.基本类型
        2.String
        3.枚举类型
        4.注解类型
        5.Class类型
        6.以上类型的一维数组类型
public @interface MyAnnotation2 {
    //注解的属性都支持那些类型?
    // 八大基本数据类型
    // String 
    // Array
    // Enum枚举

    //可以使用default关键字,添加属性的默认值
    byte a() default 10;
    short b();
    int c();
    long d();
    float e();
    double f();
    char g();
    boolean h();

    String i();

    String[] j();

    ElementType k();

}
    关于注解的属性声明后的使用:

        1.如果一个注解有属性,那么在使用注解时,要对属性进行赋值操作.
            例如:@MyAnnotation3(st = "aaa")

        2.如果一个注解的属性有多个,都需要赋值,使用","分开属性.
            @MyAnnotation3(st = "aaa",i=10)

        3.也可以给属性赋默认值
            double d() default 1.23;
            如果属性有默认值,在使用注解时,就可以不用为属性赋值。

        4.如果属性是数组类型

            1.可以直接使用   属性名={值1,值2,。。。}方式,例如

                @MyAnnotation3(st = "aaa",i=10,sts={"a","b"})
            2.如果数组的值只有一个也可以写成下面方式
                @MyAnnotation3(st = "aaa",i=10,sts="a")
                注意sts属性它是数组类型,也就是说,只有一个值时,可以省略"{}"

        5.对于属性名称 value的操作.
            1.如果属性名称叫value,那么在使用时,可以省略属性名称
                @MyAnnotation3("hello")

            2.如果有多个属性,都需要赋值,其中一个叫value,这时,必须写属性名称
                @MyAnnotation3(value="hello",i=10)

            3.如果属性名称叫value,它的类型是数组类型.
                    1.只有这个value属性
                        可以直接赋值,不能写属性名称,但是,如果只有一个值
                            @MyAnnotation3({"abc"})或  @MyAnnotation3("abc")
                        但是如果有多个值
                            @MyAnnotation3({"abc","def"})                           

                    2.如果有多个属性,属性名称叫value
                        所有属性都需要赋值,那么必须写属性名称.
关于元注解

元注解是指注解的注解。包括 @Retention @Target @Document @Inherited四种。

//元注解 (4个)
//修饰注解的注解
// @Retention 注解是给谁看的=> 永远选择RUNTIME
    //RetentionPolicy.SOURCE  注解会保留到编译期 (给编译器看)
    //RetentionPolicy.CLASS 注解会保留到加载期(给类加载器)
    //RetentionPolicy.RUNTIME 注解会保留到运行期(给虚拟机看)
//
@Retention(RetentionPolicy.RUNTIME)
//@Target 注解支持加在什么位置
    @Target(ElementType.TYPE)   //接口、类、枚举、注解
    @Target(ElementType.FIELD) //字段、枚举的常量
    @Target(ElementType.METHOD) //方法
    @Target(ElementType.PARAMETER) //方法参数
    @Target(ElementType.CONSTRUCTOR)  //构造函数
    @Target(ElementType.LOCAL_VARIABLE)//局部变量
    @Target(ElementType.ANNOTATION_TYPE)//注解
    @Target(ElementType.PACKAGE) ///包   
@Target({ElementType.CONSTRUCTOR,ElementType.METHOD,ElementType.TYPE})
//@Inherited描述 注解可否被继承
@Inherited
//@Documented 描述注解是否用于生成java文档
@Documented
public @interface MyAnnotation3 {

}
注解与银行取款的实例

首先自定义一个注解

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 {
    double value();

}

实现的银行业务类

public class BankService {

    @BankInfo(20000)
    public static void zz(String name1,String name2,double money) throws Exception{
        // 在使用注解的方法中获得注解上填写的属性值.
            //1 获得注解所在的反射对象 
    Method m =  BankService.class.getMethod("zz",String.class,String.class,double.class);
            //2 判断方法是否被@BankInfo 所修饰
            if(m.isAnnotationPresent(BankInfo.class)){
                //被修饰
                //3 获得注解的属性值
                BankInfo info = m.getAnnotation(BankInfo.class);
                double maxmoney = info.value();
                if(money>maxmoney){
                    throw new RuntimeException("单次转账不能超过"+maxmoney+"元!");
                }

                System.out.println(name1+"给"+name2+"转了"+money+"元!");
            }else{
                //没被注解修饰
                throw new RuntimeException("系统异常,不能转账!");
            }


    }

    public static void main(String[] args) throws Exception {
        zz("tom", "jerry", 10000);
    }

}
下一个事例:JDBCUtils

在以往的实例当中,我们选择以配置文件的方式来控制参数,现在我们可以用注解来完成相关参数的配置工作。

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.TYPE)//加到类上
public @interface JDBCInfo {

    //驱动名称
    String driver();
    //url地址
    String url();
    //用户名
    String name();
    //密码
    String password();

}

重写JDBC的工具类

import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

@JDBCInfo(driver = "com.mysql.jdbc.Driver", name = "root", password = "1234", url = "jdbc:mysql://localhost:3306/day05")
public class JDBCUtils {
    private static String driver;
    private static String url;
    private static String user;
    private static String password;



    static{

        try {
            //获得注解中配置的属性
            //1 获得注解所在的反射对象
            Class clazz = JDBCUtils.class;
            //2 获得注解的实现类
            JDBCInfo info = (JDBCInfo) clazz.getAnnotation(JDBCInfo.class);
            //3 获得4个属性值
            driver = info.driver();
            url=info.url();
            user=info.name();
            password=info.password();


            //1 注册驱动
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    //1 获得连接
    public static Connection getConnection(){
        Connection conn = null;
        try {
            //2 获得连接
            conn = DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("创建连接失败!");
        }

        return conn;
    }

    //2 释放资源
        //1> 参数可能为空
        //2> 调用close方法要抛出异常,确保即使出现异常也能继续关闭
        //3>关闭顺序,需要从小到大
    public  static void  close(Connection conn , Statement st , ResultSet rs){

        try {
            if(rs!=null){
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(st!=null){
                st.close(); 
                }
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                try {
                    if(conn!=null){
                        conn.close();   
                        }
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        }

    }


    public static void main(String[] args) {
        System.out.println(getConnection());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值