黑马程序员基础加强---注解

注解(未来的编程基于注解)

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

1.概述

概念:注解(也称为元数据):为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后的某个时刻非常方便地使用这些数据。

注解在一定程度上是在把元数据与源代码文件结合在一起,而不是保存在外部文档中这一大催势之下所催生的。

注解的语法比较简单,除了@符号的使用之外,它基本与Java固有的语法一致。Java SE5内置了三种,定义在java.lang中的注解

1.1 三种内置注解

1. @Override:表示当前的方法定义将覆盖超类中的方法。如果你不小心拼写错误,或者方法名对不上被覆盖的方法,编译器会发出错误的提示。

class Animal{
    public void eat(){
        System.out.println("吃饭罗!");
    }
}
class Dag extends Animal{
    //@Override表示该方法是从父类中继承下来的,方法名必须与父类某方法相等
    @Override
    public void eat(){
        System.out.println("狗吃饭");
    }
}

2.@Deprecated 如果程序员使用注解为它的元素,那么编译器会发出警告信息。

public static void main(String[] args) {
        // TODO Auto-generated method stub
        Animal ani = new Animal();
        ani.eat();
    }
}
class Animal{
    //@Deprecated该方法表示为过时的方法,可以编译可以运行,但是有该方法出现的地方就会出现警告信息
    @Deprecated
    public void eat(){
        System.out.println("吃饭罗!");
    }
}

3.@SuppressWarnings 关闭不当的编译器警告信息。

2.自定义Annotation

2.1 概述

概念:定义Annotation类型时,也需要用到定义接口的interface关键字,不过需要在interface关键字的前面加一个“@”符号,即定义Annotation类型的关键字是@interface,这个关键字隐含的意思是继承自java.lang.annotation.Annotation接口。

语法:

public @interface MyAnnotation的名称{}

2.2 标记注解(marker annotation):

没有元素的注解,如上MyAnnotation。

在注解中,一般都会包含一些元素以表示某些值。当分析处理注解时,程序或工具可以利用这些值。注解的元素看起来像接口的方法。唯一的区别是你可以为其指定默认值

如下注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
        String value()default "123";       
}

这是一个用于类、接口、枚举,运行中加载到JVM里面有一成员,其有默认值为”123”。

参数说明:

1. 注解可用的类型有八种基本类型、String、Class、Annotation、枚举、数组。

2. Value,成员名称,如果在所定义的Annotation类型中只包含一个成员,通常将名称命名为value

2.3 元注解(注解中的注解)

Java内置了有三种标准注解,以及四种均注解,元注解专职负责注解其他的注解。

代码实例:

定义一个用来注释构造方法的Annotation类型@Construction_Annotation,有效范围为在运行时加载到Annotation到JVM中;还有一个用来注释字段、方法和参数的的Annotation类型的@Field_Method_Parameter_Annotation有效范围在运动时加载Annotion到JVM中。

@Construction_Annotation的代码

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//用于构造函数
@Target(ElementType.CONSTRUCTOR)
//在运行时加载到Annotatin到JVM中
@Retention(RetentionPolicy.RUNTIME)
public @interface ConStructor_Annotation {
    //定义一个有默认值的String型成员
    String value() default "默认构造方法";
}

@Field_Method_Parameter_Annotation的代码

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//用于字段、方法和参数
@Target({ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER})
//在运行时加载Annotation到JVM中
@Retention(RetentionPolicy.RUNTIME)
public @interface Field_Method_Parameter_Annotation {
    //定义一个没有默认值的String型成员
    String describe();
    //定义一个有默认值的Class型成员
    Class type() default void.class;
}

Record的代码

public class Record {
    @Field_Method_Parameter_Annotation(describe = "编号", type = int.class)
    private int id;
    @Field_Method_Parameter_Annotation(describe = "名字" , type = String.class)
    private String name;
    //因为其有默认值所以不需要填写任何东西
    @ConStructor_Annotation
    public Record(){}
    public Record(
            //class有默认值,故可填可不填
            @Field_Method_Parameter_Annotation(describe = "编号")
            int id ,
            @Field_Method_Parameter_Annotation(describe = "名字")
            String name){
        this.id = id;
        this.name = name;
    }
    //注释方法
    @Field_Method_Parameter_Annotation(describe = "获得编号",type = int.class)
    public int getId() {
        return id;
    }
    @Field_Method_Parameter_Annotation(describe = "设置编号")
    public void setId(//注释方法参数
            @Field_Method_Parameter_Annotation(describe = "编号",type = int.class) int id)
    {
        this.id = id;
    }
    @Field_Method_Parameter_Annotation(describe = "得到名字")
    public String getName() {
        return name;
    }
    @Field_Method_Parameter_Annotation(describe = "设置名字")
    public void setName(@Field_Method_Parameter_Annotation(describe = "名字", type = String.class) String name) {
        this.name = name;
    }
}

如上可见,注解就是一种特别的注释,他会提醒用户需要做什么

3.访问Annotation信息

   如果在定义Annotation类型时将@Retention设置为RetentionPolicy.RUNTIME,那么在运行程序时通过反射就可以获取相关的Annotatin信息,如获取构造方法,字段和方法的Annotation信息。

3.1 访问Annotation的方法

代码实例(访问上述例子的Annotation):

  public static void main(String[] args) {
        // TODO Auto-generated method stub
        Class classR = null;
        Record re = new Record();
        classR = re.getClass();
        System.out.println("===================获得所有构造函数===================");
        //获得所有构造函数
        Constructor[] declaredConstructors = classR.getDeclaredConstructors();
        //遍历构造函数
        for (int i = 0; i < declaredConstructors.length; i++) {
            Constructor constructor = declaredConstructors[i];
            //查看是否具有指定类型的注解
            if (constructor.isAnnotationPresent(Constructor_Annotation.class)) {
              //获得指定类型的注解
                Constructor_Annotation ca = (Constructor_Annotation) constructor
                        .getAnnotation(Constructor_Annotation.class);
                // 获得注释的内容
                System.out.println(ca.value());
            }
            //获得参数的注解
            Annotation[][] parameterAnnotations = constructor
                    .getParameterAnnotations();
            for (int j = 0; j < parameterAnnotations.length; j++) {
                //获得指定参数注解的长度
                int length = parameterAnnotations[j].length;
                //如果长度为0,则表示没有为该参数添加注解
                if (length == 0) {
                    System.out.println("未添加Annotation参数");
                } else {
                    for (int k = 0; k < length; k++) {
                        //获得参数的注解
                        Field_Method_Parameter_Annotation pa = (Field_Method_Parameter_Annotation) parameterAnnotations[j][k];
                        //获得参数的描述与类型
                        System.out.print(pa.describe() + "  " + pa.type()
                                + "   ");
                    }
                }
                System.out.println();
            }      
        }
        System.out.println("====================获得所有字段的信息========================");
        //获得所有字段
        Field[]declaredFields = classR.getDeclaredFields();
        //遍历字段
        for(int i = 0 ; i < declaredFields.length ; i ++){
            Field field = declaredFields[i];
            //获得指定类型的注解
            if(field.isAnnotationPresent(Field_Method_Parameter_Annotation.class)){
                Field_Method_Parameter_Annotation fa = field.getAnnotation(Field_Method_Parameter_Annotation.class);
                //获得参数的描述与类型
                System.out.println(fa.describe() +  "   " + fa.type());
            }
        }
        System.out.println("=====================获得访问方法的信息===============================");
        //获得所有方法
        Method [] methods = classR.getDeclaredMethods();
        //遍历方法
        for(int i = 0 ; i < methods.length ; i ++){
            Method method = methods[i];
            //查看是否具有指定类型的注解
            if(method.isAnnotationPresent(Field_Method_Parameter_Annotation.class)){
                //获得指定类型的注解
                Field_Method_Parameter_Annotation ma = method.getAnnotation(Field_Method_Parameter_Annotation.class);
                //获得方法的描述与返回值类型
                System.out.println(ma.describe() + "  " + ma.type() );
            }
            //获得方法的注解
            Annotation [] []parameterAnnotations = method.getParameterAnnotations();
            for(int j = 0 ; j < parameterAnnotations.length ; j ++ ){
                //获得指定注解的长度
                int length = parameterAnnotations[j].length;
                //如果长度为0,则表示没有为该参数添加注解
                if(length == 0){
                    System.out.println("未指定类型的注释");
                }else{
                    for(int k = 0 ; k < length ; k ++){
                        //获得指定类型的注解
                        Field_Method_Parameter_Annotation pa = (Field_Method_Parameter_Annotation)parameterAnnotations[j][k];
                        //获得参数的描述与类型
                        System.out.print(pa.describe() +  "\n   " + pa.type());
                    }
                }
                System.out.println();
            }
        }
    }
}
输出:
===================获得所有构造函数===================
默认构造方法
有参构造函数
编号  int  
名字  class java.lang.String  
====================获得所有字段的信息========================
编号   int
名字   class java.lang.String
=====================获得访问方法的信息===============================
设置编号  void
编号
   int
得到名字  class java.lang.String
获得编号  int
设置名字  void
名字
   class java.lang.String

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值