码迷,mamicode.com
首页 > 其他好文 > 详细

3.注解

时间:2019-08-24 23:02:44      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:stat   类加载器   字节   des   interface   基本数据类型   val   警告   内容   

       1. 注解概念

              注释:

                     给人看的提示信息,人看了提示信息了解程序的内容

                     java中注释的格式://  /**/  /** */

              注解:

                     sun在jdk5.0开始提供的新特性

                     给程序看的提示信息,程序看后可以根据有无注解及注解上属性的不同配置执行不同的逻辑。

                     java中的注解的格式:@AnnoName(key=value,...)

                    

              **注解在开发中,可以作为轻量化配置来使用,比起使用xml作为配置文件,更加的轻便易用,在java开发中大量的使用。

       2. jdk内置注解

              @Override

                     声明重写父类方法的注解,要求编译器帮我们检查是否成功的覆盖,如果没有成功覆盖父类方法,编译器将会进行报错提示。

              @Deprecated

                     声明方法被过时,不再建议使用,要求编译器在编译的过程中对于这样的方法的调用提出警告,提示方法过时。

              @SuppressWarnings

                     压制警告,提示编译器,在编译的过程中对指定类型的警告不再提示。

             

@SuppressWarnings("unused")
        int i;

 

       3. 自定义注解开发

 

              a. 开发一个注解类

                     开发一个注解类的过程,非常类似于开发一个接口,只不过需要通过@interface关键字来声明

              b. 使用元注解修饰注解的声明

                     所谓的元注解是用来修饰注解声明的注解,可以控制被修饰的注解的特性。

                     i. @Target

                            用来声明被修饰的注解可以用在什么位置。

                            可以在@Target的属性中设置ElementType类型的数组来指定可以使用的位置。

                            如果不用此元注解修饰,默认注解可以用在任意位置。

public enum ElementType {
    /**用于描述类、接口(包括注解类型) 或enum声明 Class, interface Type是class的父接口*/
    TYPE,
 
    /** 用于描述成员属性 */
    FIELD,
 
    /**用于描述方法*/
    METHOD,
 
    /**用于描述方法参数 */
    PARAMETER,
 
    /**用于描述构造器  */
    CONSTRUCTOR,
 
    /**用于描述局部变量 */
    LOCAL_VARIABLE,
 
    /** 全局变量*/
    ANNOTATION_TYPE,
 
    /**用于描述包  */
    PACKAGE,
 
    /**
     * 用来标注类型参数 
     * @since 1.8
     */
    TYPE_PARAMETER,
 
    /**
     *能标注任何类型名称 
     * @since 1.8
     */
    TYPE_USE

注解有个潜在的规则就是当你的注解参数只有一个的时候且为values的话values可以不写,而且当你只有一个注解参数{}可以不写

                     ii. @Retention

                            用来声明被修饰的注解会被保留到什么阶段。

                     .java->编译器->.class->类加载器->字节码(运行起来就变成内存中的字节码)

                            可以在该注解的属性中通过RetentionPolicy类型的值来指定注解被保留到何时。

                                   a) RetentionPolicy.SOURCE

                                          此注解将会被保留到源码阶段,.java中,在编译过程中被删除。

                                          这种类型的注解通常是给编译器看的。

                                   b) RetentionPolicy.CLASS

                                          此注解将会被保留在源码阶段 和 编译阶段 ,.java和.class中,在类加载的过程中被删除。

                                          这种类型的注解通常是给类加载器看的。

                                   c) RetentionPolicy.RUNTIME

                                          此注解将会被保留在源码阶段 、编译阶段 和 运行阶段,.java .class和内存中的字节码中都会存在。

                                          这种类型的注解通常用来在运行阶段进行反射,控制程序运行过程。

                                          **只有RUNTIME级别的注解才可以通过反射技术进行反射。

    @Override、@SuppressWarnings是默认保留到SOURCE阶段;@Deprecated是保留到RUNTIME阶段。

                     iii. @Documented

                            用来声明被修饰注解是否要被文档提取工具提取到文档中。

                            默认不提取。

                     iv. @Inherited

                            被修饰的注解是否具有继承性

                            默认没有继承性

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value= {ElementType.TYPE})
@Retention(value=RetentionPolicy.RUNTIME)
public @interface FirstAno {

}

 

              c. 为注解增加属性

                     注解类中还可以声明属性。

                     为注解类声明属性的过程非常类似于为接口定义方法。

                     但要求,注解中的所有的属性必须是public的,可以显式声明,也可以不声明,不声明默认就是public的。

                     注解中的属性只能是八种基本数据类型 String类型 Class类型 枚举类型  其他注解类型 及 以上类型的一维数组。

                     注解中声明的属性 需要在使用注解时 为其赋值 赋值的方式 就是使用注解时 在注解后跟一对小括号 在其中 通过 属性名=属性值 的方式 指定属性的值

                     也可以在声明注解时 在注解的属性后 通过default关键字 声明属性的默认值 声明过默认值的属性 可以在使用注解时 不赋值 则默认采用默认值 也可以手动赋值 覆盖默认值

                     如果属性是 一维数组类型 而 在传入的数组中 只有一个值 则包括数组的大括号可以省略

                     如果注解的属性 只有一个需要赋值 且该属性的名称叫做value 则在使用注解时 value= 可以不写

package cn.tedu.anno;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FirstAnno {
    String name() default "zs";
    String [] addrs() default "bj";
    String value();
}
@FirstAnno(value="zzz",name="徐旺骑")
public class Student {
    private String name;
    private int age;
    
    public Student(String name,int age) {
        this.name = name;
        this.age = age;
    }

       4. 反射注解

              a. 反射注解的原理

                     RetentionPolicy.RUNTIME级别的注解会保留到运行期,可以通过反射技术获取,从而可以根据是否有注解 或 注解属性值的不同控制程序按照不同方式运行。

                     以下反射相关的类型中都提供了反射注解的方法:

类 Class<T>、类 Method、类 Field、类 Constructor<T>、类 Package

 boolean

isAnnotationPresent(Class<? extends Annotation> annotationClass)

          如果指定类型的注释存在于此元素上,则返回 true,否则返回 false。

<A extends Annotation>

A

getAnnotation(Class<A> annotationClass)

          如果存在该元素的指定类型的注解,则返回这些注解,否则返回 null。

 Annotation[]

getAnnotations()

          返回此元素上存在的所有注解。

 

package cn.tedu.test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

enum PL{
    协警,交警,刑警,警督
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface level{
    PL value() default PL.协警;
}

@level(PL.警督)
class Police{
    public static void fakuan() {
        System.out.println("您好,您超速了,罚款200元..");
    }
}

public class Test02 {
    public static void main(String[] args) {
        Police.fakuan();
        if(Police.class.isAnnotationPresent(level.class)) { //判断police这个类上有没有level这个注解
            //真警察
            level anno = Police.class.getAnnotation(level.class);
            if(anno.value()==PL.协警) {
                System.out.println("大哥,少罚点,交50得了...");
            }else if(anno.value() == PL.交警) {
                System.out.println("交钱走人..");
            }else if(anno.value() == PL.刑警) {
                System.out.println("交钱赶紧走,别查出别的事..");
            }else {
                System.out.println("领导抽根烟,这是200块,不够还有..");
            }
        }else {
            //假警察
            System.out.println("打一顿,扭送派出所..");
        }
    }
}

 

3.注解

标签:stat   类加载器   字节   des   interface   基本数据类型   val   警告   内容   

原文地址:https://www.cnblogs.com/xuwangqi/p/11406248.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!