Java 中的注解详解及示例代码

在Java中,注解(Annotation)引入始于Java5,用来描述Java代码的元信息,通常情况下注解不会直接影响代码的执行,尽管有些注解可以用来做到影响代码执行。

注解可以做什么

Java中的注解通常扮演以下角色

  1. 编译器指令
  2. 构建时指令
  3. 运行时指令

其中

  1. Java内置了三种编译器指令,本文后面部分会重点介绍
  2. Java注解可以应用在构建时,即当你构建你的项目时。构建过程包括生成源码,编译源码,生成xml文件,打包编译的源码和文件到JAR包等。软件的构建通常使用诸如Apache Ant和Maven这种工具自动完成。这些构建工具会依照特定的注解扫描Java代码,然后根据这些注解生成源码或文件。
  3. 通常情况下,注解并不会出现在编译后的代码中,但是如果想要出现也是可以的。Java支持运行时的注解,使用Java的反射我们可以访问到这些注解,运行时的注解的目的通常是提供给程序和第三方API一些指令。

注解基础

一个简单的Java注解类似与@Entity。其中@的意思是告诉编译器这是一个注解。而Entity则是注解的名字。通常在文件中,写法如下

public @interface Entity {
}

注解元素

Java注解可以使用元素来进行设置一些值,注解中的元素类似于属性或者参数。定义包含元素的注解示例代码

public @interface Entity {
  String tableName();
}

使用包含元素的注解示例代码

@Entity(tableName = "vehicles")

上述注解的元素名称为tableName,设置的值为vehicles。没有元素的注解不需要使用括号。

如果注解包含多个元素,使用方法如下

@Entity(tableName = "vehicles", primaryKey = "id")

如果注解只有一个元素,通常我们的写法是这样的

@InsertNew(value = "yes")

但是这种情况下,当且仅当元素名为value,我们也可以简写,即不需要填写元素名value,效果如下

@InsertNew("yes")

注解使用

注解可以用来修饰代码中的这些元素

  1. 接口
  2. 方法
  3. 方法参数
  4. 属性
  5. 局部变量

一个完整的使用示例如下

@Entity
public class Vehicle {

  @Persistent
  protected String vehicleName = null;

  @Getter
  public String getVehicleName() {
    return this.vehicleName;
  }

  public void setVehicleName(@Optional vehicleName) {
    this.vehicleName = vehicleName;
  }

  public List addVehicleNameToList(List names) {

    @Optional
    List localNames = names;

    if(localNames == null) {
      localNames = new ArrayList();
    }
    localNames.add(getVehicleName());

    return localNames;
  }

}

内置的Java注解

Java中有三种内置注解,这些注解用来为编译器提供指令。它们是

  1. @Deprecated
  2. @Override
  3. @SuppressWarnings

@Deprecated

可以用来标记类,方法,属性。
如果上述三种元素不再使用,使用@Deprecated注解
如果代码使用了@Deprecated注解的类,方法或属性,编译器会进行警告。

@Deprecated使用很简单,如下为注解一个弃用的类。

@Deprecated
public class MyComponent {

}

当我们使用@Deprecated注解后,建议配合使用对应的@deprecated JavaDoc符号,并解释说明为什么这个类,方法或属性被弃用,已经替代方案是什么。

@Deprecated
/**
 @deprecated This class is full of bugs. Use MyNewComponent instead.
*/
public class MyComponent {

}

@Override

@Override注解用来修饰对父类进行重写的方法。如果一个并非重写父类的方法使用这个注解,编译器将提示错误。

实际上在子类中重写父类或接口的方法,@Overide并不是必须的。但是还是建议使用这个注解,在某些情况下,假设你修改了父类的方法的名字,那么之前重写的子类方法将不再属于重写,如果没有@Overide,你将不会察觉到这个子类的方法。有了这个注解修饰,编译器则会提示你这些信息。

使用Override注解的例子

public class MySuperClass {

  public void doTheThing() {
    System.out.println("Do the thing");
  }
}

public class MySubClass extends MySuperClass{

  @Override
  public void doTheThing() {
    System.out.println("Do it differently");
  }
}

@SuppressWarnings

@SuppressWarnings用来抑制编译器生成警告信息。

可以修饰的元素为类,方法,方法参数,属性,局部变量

使用场景:当我们一个方法调用了弃用的方法或者进行不安全的类型转换,编译器会生成警告。我们可以为这个方法增加

@SuppressWarnings注解,来抑制编译器生成警告。

注意:使用@SuppressWarnings注解,采用就近原则,比如一个方法出现警告,我们尽量使用@SuppressWarnings注解这个方法,而不是注解方法所在的类。虽然两个都能抑制编译器生成警告,但是范围越小越好,因为范围大了,不利于我们发现该类下其他方法的警告信息。

使用示例

@SuppressWarnings
public void methodWithWarning() {

}

创建自己的注解

在Java中,我们可以创建自己的注解,注解和类,接口文件一样定义在自己的文件里面。如下

@interface MyAnnotation {
  String  value();
  String  name();
  int   age();
  String[] newNames();
}

上述代码定义了一个叫做MyAnnotation的注解,它有4个元素。再次强调一下,@interface这个关键字用来告诉java编译器这是一个注解。

仔细一看,你会发现,注解元素的定义很类似于接口的方法。这些元素有类型和名称。这些类型可以是

  1. 原始数据类型
  2. String
  3. Class
  4. annotation
  5. 枚举
  6. 一维数组

如下为应用自定义的注解

@MyAnnotation(
  value="123",
  name="Jakob",
  age=37,
  newNames={"Jenkov", "Peterson"}
)
public class MyClass {

}

注意,我们需要为所有的注解元素设置值,一个都不能少。

注解元素默认值

对于注解中的元素,我们可以为其设置默认值,使用方法为

@interface MyAnnotation {
  String  value() default "";
  String  name();
  int   age();
  String[] newNames();
}

上述代码,我们设置了value元素的默认值为空字符串。当我们在使用时,可以不设置value的值,即让value使用空字符串默认值。 使用示例代码

@MyAnnotation(
  name="Jakob",
  age=37,
  newNames={"Jenkov", "Peterson"}
)
public class MyClass {

}

@Retention

@Retention是用来修饰注解的注解,使用这个注解,我们可以做到

控制注解是否写入class文件
控制class文件中的注解是否在运行时可见

控制很简单,使用使用以下三种策略之一即可。

RetentionPolicy.SOURCE 表明注解仅存在源码之中,不存在.class文件,更不能运行时可见。常见的注解为@Override, @SuppressWarnings。
RetentionPolicy.CLASS 这是默认的注解保留策略。这种策略下,注解将存在与.class文件,但是不能被运行时访问。通常这种注解策略用来处于一些字节码级别的操作。
RetentionPolicy.RUNTIME 这种策略下可以被运行时访问到。通常情况下,我们都会结合反射来做一些事情。

@Retention的使用示例

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

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
  String  value() default "";
}

@Target

使用@Target注解,我们可以设定自定义注解可以修饰哪些java元素。简单示例

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

@Target({ElementType.METHOD})
public @interface MyAnnotation {
  String  value();
}

上述的代码说明MyAnnotation注解只能修饰方法。

@Target可以选择的参数值有如下这些

  1. ElementType.ANNOTATION_TYPE(注:修饰注解)
  2. ElementType.CONSTRUCTOR
  3. ElementType.FIELD
  4. ElementType.LOCAL_VARIABLE
  5. ElementType.METHOD
  6. ElementType.PACKAGE
  7. ElementType.PARAMETER
  8. ElementType.TYPE(注:任何类型,即上面的的类型都可以修饰)

@Inherited

如果你想让一个类和它的子类都包含某个注解,就可以使用@Inherited来修饰这个注解。

java.lang.annotation.Inherited

@Inherited
public @interface MyAnnotation {

}
1
2
@MyAnnotation
public class MySuperClass { ... }
1
public class MySubClass extends MySuperClass { ... }

上述代码的大致意思是

1.使用@Inherited修饰注解MyAnnotation
2.使用MyAnnotation注解MySuperClass
3.实现一个类MySubclass继承自MySuperClass

通过以上几步,MySubClass也拥有了MyAnnotation注解。

关于Java中的注解,一些基本的概念就是这些。

以上 就是关于Java 中的注解资料整理,后续继续补充相关资料,谢谢大家对本站的支持!

(0)

相关推荐

  • Java 什么是注解及注解原理详细介绍

    Java 注解的原理 java : 注解使用,http://www.jb51.net/article/101747.htm 什么是注解 注解也叫元数据,例如我们常见的@Override和@Deprecated,注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包.类.接口.字段.方法参数.局部变量等进行注解.它主要的作用有以下四方面: 生成文档,通过代码里标识的元数据生成javadoc文档. 编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证. 编译时动态处理,编译

  • java中@ModelAttribute注解的作用

    问题描述:当我们使用表单传值得时候,如果定义了,name,address,age.等属性,那么通过表单传过去的值就只有这3个属性,但是我们需要的name,pass,address,age等四个属性.那么在提交表单并赋值的时候就会出现,未得到的值为null的情况.如下图: 获取的pass为null 那么我们需要用@ModelAttribute注解来解决他: 实现代码如下: @ModelAttribute public void getUsers(@RequestParam(value="name&

  • JAVA 注解详解及简单实例

    JAVA 注解详解及简单实例 何为注解 注解(Annotation)又称为元数据,在JDK1.5后引入,它的作用是: 生成文档  这是注解的原始用途,可以通过注解生成JavaDoc文档 跟踪代码的依赖性  可以通过注解替代配置文件,简化项目的配置.现有的许多框架都采用这个功能减少自己的配置. 编译检查  在编译时进行格式检查,例如@Override 基础注解 Java目前内置了三种标准注解,以及四种元注解.四种元注解负责创建其他的注解. 三种标准注解 @Override,表示当前的方法覆盖超类中

  • 深入理解Java注解类型(@Annotation)

    Java注解是在JDK5时引入的新特性,鉴于目前大部分框架(如spring)都使用了注解简化代码并提高编码的效率,因此掌握并深入理解注解对于一个Java工程师是来说是很有必要的事.本篇我们将通过以下几个角度来分析注解的相关知识点 理解Java注解 实际上Java注解与普通修饰符(public.static.void等)的使用方式并没有多大区别,下面的例子是常见的注解: public class AnnotationDemo { //@Test注解修饰方法A @Test public static

  • java javax.annotation.Resource注解的详解

    java 注解:java javax.annotation.Resource  当我们在xml里面为类配置注入对象时,会发现xml文件会越来越臃肿,维护起来很麻烦.这时候我们可以使用注解这种机制来为类配置注入对象. Java为我们提供了 javax.annotation.Resource这个注解. spring框架提供了org.springframework.beans.factory.annotation.Autowired. 一般情况下我们使用 javax.annotation.Resour

  • java 注解annotation的使用以及反射如何获取注解

     一.注解基本知识 1.元注解 元注解是指注解的注解.包括  @Retention @Target @Document @Inherited四种. 1. Annotation型定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口. 2. 参数成员只能用public或默认(default)这两个访问权修饰 3. 参数成员只能用基本类型byte,short,char,int,long,float,doubl

  • Java自定义注解实现Redis自动缓存的方法

    在实际开发中,可能经常会有这样的需要:从MySQL中查询一条数据(比如用户信息),此时需要将用户信息保存至Redis. 刚开始我们可能会在查询的业务逻辑之后再写一段Redis相关操作的代码,时间长了后发现这部分代码实际上仅仅做了Redis的写入动作,跟业务逻辑没有实质的联系,那么有没有什么方法能让我们省略这些重复劳动呢? 首先想到用AOP,在查询到某些数据这一切入点(Pointcut)完成我们的切面相关处理(也就是写入Redis).那么,如何知道什么地方需要进行缓存呢,也就是什么地方需要用到AO

  • java @interface 注解详解及实例

    java @interface 注解详解及实例 1 简介 在Java中,定义注解其实和定义接口差多不,只需要在interface前添加一个@符号就可以,即 @interface Zhujie{ },这就表明我们定义了一个名为 @Zhujie 的注解.注解中的每一个方法定义了这个注解类型的一个元素,特别注意:注解中方法的声明中一定不能包含参数,也不能抛出异 常:方法的返回值被限制为简单类型.String.Class.emnus.注释,和这些类型的数组,但方法可以有一个缺省值. 注解相当于一种标记,

  • java基于spring注解AOP的异常处理的方法

    一.前言 项目刚刚开发的时候,并没有做好充足的准备.开发到一定程度的时候才会想到还有一些问题没有解决.就比如今天我要说的一个问题:异常的处理.写程序的时候一般都会通过try...catch...finally对异常进行处理,但是我们真的能在写程序的时候处理掉所有可能发生的异常吗? 以及发生异常的时候执行什么逻辑,返回什么提示信息,跳转到什么页面,这些都是要考虑到的. 二.基于@ControllerAdvice(加强的控制器)的异常处理 @ControllerAdvice注解内部使用@Except

  • Java 中的注解详解及示例代码

    在Java中,注解(Annotation)引入始于Java5,用来描述Java代码的元信息,通常情况下注解不会直接影响代码的执行,尽管有些注解可以用来做到影响代码执行. 注解可以做什么 Java中的注解通常扮演以下角色 编译器指令 构建时指令 运行时指令 其中 Java内置了三种编译器指令,本文后面部分会重点介绍 Java注解可以应用在构建时,即当你构建你的项目时.构建过程包括生成源码,编译源码,生成xml文件,打包编译的源码和文件到JAR包等.软件的构建通常使用诸如Apache Ant和Mav

  • Java中初始化块详解及实例代码

    Java中初始化块详解 在Java中,有两种初始化块:静态初始化块和非静态初始化块. 静态初始化块:使用static定义,当类装载到系统时执行一次.若在静态初始化块中想初始化变量,那仅能初始化类变量,即static修饰的数据成员. 非静态初始化块:在每个对象生成时都会被执行一次,可以初始化类的实例变量. 非静态初始化块会在构造函数执行时,且在构造函数主体代码执行之前被运行. 括号里的是初始化块,这里面的代码在创建Java对象时执行,而且在构造器之前执行! 其实初始化块就是构造器的补充,初始化块是

  • Java中的静态内部类详解及代码示例

    1. 什么是静态内部类 在Java中有静态代码块.静态变量.静态方法,当然也有静态类,但Java中的静态类只能是Java的内部类,也称为静态嵌套类.静态内部类的定义如下: public class OuterClass { static class StaticInnerClass { ... } } 在介绍静态内部类之前,首先要弄清楚静态内部类与Java其它内部类的区别. 2. 内部类 什么是内部类?将一个类的定义放在另一个类的内部,就是内部类.Java的内部类主要分为成员内部类.局部内部类.

  • Java中的HashSet详解和使用示例_动力节点Java学院整理

    第1部分 HashSet介绍 HashSet 简介 HashSet 是一个没有重复元素的集合. 它是由HashMap实现的,不保证元素的顺序,而且HashSet允许使用 null 元素. HashSet是非同步的.如果多个线程同时访问一个哈希 set,而其中至少一个线程修改了该 set,那么它必须 保持外部同步.这通常是通过对自然封装该 set 的对象执行同步操作来完成的.如果不存在这样的对象,则应该使用 Collections.synchronizedSet 方法来"包装" set.

  • Java 中的HashMap详解和使用示例_动力节点Java学院整理

    第1部分 HashMap介绍 HashMap简介 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口. HashMap 的实现不是同步的,这意味着它不是线程安全的.它的key.value都可以为null.此外,HashMap中的映射不是有序的. HashMap 的实例有两个参数影响其性能:"初始容量" 和 "加载因子&quo

  • Java中Volatile关键字详解及代码示例

    一.基本概念 先补充一下概念:Java内存模型中的可见性.原子性和有序性. 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情.为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制. 可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的.也就是一个线程修改的结果.另一个线程马上就能看到.比如:用volatile修饰的变量,就会具有可见性.volatile修饰的

  • Java中File类方法详解以及实践

    目录 File类概述 File类常用构造器 File类常用方法 常用方法示例 createTempFile临时文件创建示例 FilenameFilter文件过滤器示例 总结 File类概述 File类是java.io包下代表与平台无关的文件和目录.File可以新建.删除.重命名文件和目录,但是不能访问文件内容本身,如果需要访问内容的话,需要通过输入/输出流进行访问. File类可以使用文件路径字符串创建File实例,路径既可以是绝对路径,也可以是相对路径.一般相对路径的话是由系统属性user.d

  • java中正则表达式实例详解

    Java中正则表达式运用实例(参看java中正则表达式运用详解): 测试代码 package test; /** * 在String的matches()方法,split()方法中使用正则表达式. * @author fhd001 */ public class RegexTest { public static void main(String[] args) { /* * 普通字符 */ String str1 = "abc45abc345"; String[]arr1 = str1

  • java 中cookie的详解及简单实例

    java 中cookie的详解 Java对cookie的操作比较简单,主要介绍下建立cookie和读取cookie,以及如何设定cookie的生命周期和cookie的路径问题. 建立一个无生命周期的cookie,即随着浏览器的关闭即消失的cookie,代码如下 HttpServletRequest request HttpServletResponse response Cookie cookie = new Cookie("cookiename","cookievalue&

  • Java中final关键字详解

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法. 主要介绍:一.final关键字的基本用法.二.深入理解final关键字 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和局部变量).下面就从这三个方面来了解一下final关键字的基本用法. 1.修饰类 当用final修饰一个类时,表明这个类不能

随机推荐