java注解学习

一、概念

  Annotation(注解)是JDK1.5及以后版本引入的。它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查。注解是以‘@注解名’在代码中存在的,根据注解参数的个数,我们可以将注解分为:标记注解单值注解完整注解三类。它们都不会直接影响到程序的语义,只是作为注解(标识)存在,我们可以通过反射机制编程实现对这些元数据(用来描述数据的数据)的访问。另外,你可以在编译时选择代码里的注解是否只存在于源代码级,或者它也能在class文件、或者运行时中出现(SOURCE/CLASS/RUNTIME)。

  简单来说,java中的注解是附加在代码上的原信息,用于一些工具在编译、运行时解析使用,起到了说明、配置的作用。它不会影响代码的逻辑,仅仅是起到了辅助性的作用。

二、用处

如果要对于元数据的作用进行分类,还没有明确的定义,不过我们可以根据它所起的作用,大致可分为三类

编写文档:通过代码里标识的元数据生成文档。

代码分析:通过代码里标识的元数据对代码进行分析。

编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查

三、内置注解

1、@Override

它的作用是对覆盖父类中方法的方法进行标记,如果被标记的方法并没有实际覆盖父类中的方法,则编译器会发出错误警告。

@Override
public String toString() {
    return "重写toString()";
}
2、@Deprecated

它的作用是对不应该再使用的方法添加注解,当编程人员使用这些方法时,将会在编译时显示提示信息。

class Example{
    @Deprecated
    public static void print(){
    }
}

3、@SuppressWarnings

SuppressWarning不是一个标记类型注解。它有一个类型为String[]的成员,这个成员的值为被禁止的警告名。

其参数有:

  1. deprecation,使用了过时的类或方法时的警告

  2. unchecked,执行了未检查的转换时的警告

  3. fallthrough,当 switch 程序块直接通往下一种情况而没有 break 时的警告

  4. path,在类路径、源文件路径等中有不存在的路径时的警告

  5. serial,当在可序列化的类上缺少serialVersionUID 定义时的警告

  6. finally ,任何 finally 子句不能正常完成时的警告

  7. all,关于以上所有情况的警告

     public static List list = new ArrayList();
    
     @SuppressWarnings("unchecked")
     public void add(String data) {
         list.add(data);
     }
    

四、元注解

java.lang.annotation提供了四种元注解,专门注解其他的注解(在自定义注解的时候,需要使用到元注解):
@Documented –注解是否将包含在JavaDoc中

@Retention –什么时候使用该注解

@Target –注解用于什么地方

@Inherited – 是否允许子类继承该注解

1、@Documented

将注解信息加入到java文档中,Documented是一个标记注解,没有成员。

2、@Retention-用于描述注解的生命周期

RetentionPolicy.SOURCE : 在编译阶段丢弃,即在源文件中有效(源文件保留)。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。

RetentionPolicy.CLASS : 在类加载的时候丢弃,在class文件中有效(class保留)在字节码文件的处理中有用。注解默认使用这种方式

RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解(运行时保留),因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。

3、@Target – 表示该注解的使用范围

默认值为任何元素,表示该注解用于什么地方。可用的ElementType参数包括

ElementType.CONSTRUCTOR:用于描述构造器

ElementType.FIELD:成员变量、对象、属性(包括enum实例)

ElementType.LOCAL_VARIABLE:用于描述局部变量

ElementType.METHOD:用于描述方法

ElementType.PACKAGE:用于描述包

ElementType.PARAMETER:用于描述参数

ElementType.TYPE:用于描述类、接口(包括注解类型) 或enum声明

4、@Inherited

@Inherited 元注解是一个标记注解,@Inherited阐述了某个被标注类型是被继承的。如果一个使用了@Inherited修饰的annotation类型用于一个class,则这个annotation将被用于该class的子类。

五、自定义注解

自定义注解类编写的一些规则:

  1. Annotation型定义为 @interface , 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口。

  2. 参数成员只能用public或默认(default)这两个访问权修饰

  3. 参数成员只能使用byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组.

  4. 要获取类方法和字段的注解信息,必须通过Java的反射技术来获取 Annotation对象,因为你除此之外没有别的获取注解对象的方法

  5. 注解也可以没有定义成员,自定义注解需要使用到元注解

代码案例:

自定义注解

package com.annnotation;
import java.lang.annotation.*;

//元注解,设置自定义注解的生命周期
@Retention(RetentionPolicy.RUNTIME)
//元注解,设置自定义注解的参数类型
@Target(ElementType.FIELD)
@Documented
@Inherited
public @interface ColumnName {
    //该自定义注解里面只有一个变量成员名称
    public String name() default "";

}

创建实体了,并使用自定义注解

package com.annnotation;

public class Student {

    @ColumnName(name = "stuName")
    String name;

    @ColumnName(name = "stuAge")
    int age;

    @ColumnName(name = "stuSex")
    String sex;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}

测试类,使用反射获得一条sql查询语句

public static void main(String[] args) throws ClassNotFoundException {

        Class<?> demo=Class.forName("com.annnotation.Student");
        Field[] fields=demo.getDeclaredFields();
        String sql="select ";
        String link="";

        for (Field field : fields) {
            //获得每个成员的注解
//           Annotation[] annotations = field.getAnnotations();
//            for (int i = 0; i < annotations.length; i++) {
//                System.out.println(annotations[i]);
//            }

            //获得自定义注解对象
            ColumnName columnName=field.getAnnotation(ColumnName.class);

            //判断注解是不是自定义注解类型
            if(field.isAnnotationPresent(ColumnName.class) && columnName!=null){
                sql+=link+columnName.name();
            }else{
                sql+=link+field.getName();
            }
            link=",";
        }
        sql+=" from Student";
        System.out.println(sql);
    }
}

结果

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值