您的位置:首页 > 编程语言 > Java开发

java:注解(一)

2017-02-08 16:31 459 查看

什么是注解

注解(Annotation),也叫(metadata)元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。这些信息被存储在Annotation的“name=value”结构对中。

那么你可能又有疑问什么是(metadata)元数据呢?

这个解释起来比较抽象,我的理解是:“数据的数据”。

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

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

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

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

注解的分类

根据注解的参数个数分类:

标记注解。一个没有成员的 Annotation,这种类型仅仅使用自身的存在与否来为我们提供信息。标记注解非常常见,比如上面所说的 @Override
@override,就是标记注解

单值注解。成员的参数为单个参数

完整注解。成员的参数为多个参数

根据注解使用的方法和用途分类:

JDK内置系统注解

元注解

自定义注解

它们都不会直接影响到程序的语义,只是作为注解(标识)存在,我们可以通过反射机制编程实现对这些元数据(用来描述数据的数据)的访问。另外,你可以在编译时选择代码里的注解是否只存在于源代码级,或者它也能在class文件、或者运行时中出现(SOURCE/CLASS/RUNTIME)。下面我具体根据注解使用的方法和用途分类来讲解。

内置注解

内置注解分为三类:

@Override

@Deprecated

@SuppressWarnings

[b]1、@Override[/b]
它的作用是对覆盖超类中方法的方法进行标记,如果被标记的方法并没有实际覆盖超类中的方法,则编译器会发出错误警告。换句话理解就是重写父类方法,方法前的标记。

@Override
protected void onStart() {
super.onStart();
}

[b]2、@Deprecated[/b]
它的作用是对不应该再使用的方法添加注解,当编程人员使用这些方法时,将会在编译时显示提示信息,它与javadoc里的@deprecated标记有相同的功能。

public class User {

@Deprecated
public static String getName(){
return "user";
}

}

调用 getName 方法:

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//@Deprecated 方法已经过时 出现中划线
User.getName();

}

}

[b]3、@SuppressWarnings[/b]
其参数有:

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

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

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

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

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

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

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

public class User {

@SuppressWarnings("deprecation")
public static int getAge() {
return 18;
}

}


[/code]

元注解

元注解就是定义注解的注解,由 java API 提供,分别有四个元注解:

@Target

@Retention

@Documented

@Inherited

[b]1、@Target[/b]
用于描述注解的使用范围。修饰的对象范围:packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如 catch 参数)。

它的值在枚举类 ElemenetType 中:

CONSTRUCTOR: 用于描述构造器

FIELD : 用于描述域

LOCAL_VARIABLE: 用于描述局部变量

METHOD : 用于描述方法

PACKAGE : 用于描述包

PARAMETER : 用于描述参数

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

Mode类可以注解类的成员变量:

@Target(ElementType.FIELD)
@Documented
public @interface Mode {
public int value() default 0;
}

Person可以注解类、接口(包括注解类型)、或者enum声明:

@Target(ElementType.TYPE)
public @interface People {
public String value() default "";
}

[b]2、@Retention[/b]
表示需要在什么级别保存该注释信息,用于描述注解的生命周期(即:被描述的注解在什么范围内有效),定义了该Annotation被保留的时间长短:某些Annotation仅出现在源代码中,而被编译器丢弃;而另一些却被编译在class文件中;编译在class文件中的Annotation可能会被虚拟机忽略,而另一些在class被装载时将被读取。

RetentionPoicy取值:

SOURCE : 在源文件中有效(即源文件保留)

CLASS : 在class文件中有效(即class保留)

RUNTIME : 在运行时有效(即运行时保留)

Page 注解的RetentionPolicy 的值为 RUNTIME,这样注解处理器可以通过反射,获取到该注解的属性,从而做一些运行时的逻辑处理。

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Page {
public int value() default 1;
}

[b]3、@Documented[/b]
用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,Documented 是一个标记注解,没有成员。将此注解包含在 javadoc 中 ,它代表着此注解会被javadoc工具提取成文档。在doc文档中的内容会因为此注解的信息内容不同而不同。

@Documented
public @interface Page {
public int value() default 0;
}

[b]4、@Inherited[/b]
允许子类继承父类中的注解,是一个标记注解,@Inherited阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation

当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: