java注解

来源:互联网 发布:mac触摸板怎么用 编辑:程序博客网 时间:2024/06/10 18:59

注解是java1.5版本更新的功能。
Jdk中自带三个基本的注解:

1.Override2.Deprecated3.Suppresswarnings

他们分别用于继承方法的重写,不推荐外部调用,以及忽略一些警告信息。Override是最常见的注解了,不再说明之。Deprecated注解的属性,如果被调用则会有个警告,说这个属性已经不推荐使用了。Suppresswarning则是用在某些有警告的函数中,可以忽略这些警告。

自带的三个注解功能有限,注解更多的时候需要自定义。为了更好的完成自定义注解,jdk中定义了4个元注解,来对自定义注解进行注解。注解是类级别的类型,因而可以单独写一个java文件来声明注解,注解的关键字是@interface,他和接口长得很像,也都是类级别的。元注解四个形式:

1.Target2.Retention3.Documented4.Inherited

Target修饰注解的作用对象,指定注解可以写在什么地方(如类上,字段上,方法上),如果不写则是哪里都可以。Retention是解释注解作用的时间即生命周期(如只在文件中编译时消失,编译时有用运行时消失,运行时也起作用三种),形式1相当于简单的注释,形式3则可以用反射的形式解析,因而形式三用的较多。Documented则是表明该注解会在javadoc指令运行时生成到文档中。Inherited阐述了某个被标注的类型是被继承的。用的最多的还是前两个,以下是其可用的值。

1.@Target(ElementType.TYPE) —— 可以适用于任何类的元素
2.@Target(ElementType.FIELD) —— 只适用于字段或属性
3.@Target(ElementType.METHOD) —— 只适用于方法的注解
4.@Target(ElementType.PARAMETER) —— 只适用于方法的参数
5.@Target(ElementType.CONSTRUCTOR) —— 只适用于构造函数
6.@Target(ElementType.LOCAL_VARIABLE) —— 只适用于局部变量
7.@Target(ElementType.ANNOTATION_TYPE) —— 指明声明类型本身是一个注解类型

1.@Retention(RetentionPolicy.SOURCE):在源文件中有效(即源文件保留)
2.@Retention(RetentionPolicy.CLASS):在class文件中有效(即class保留)
3.@Retention(RetentionPolicy.RUNTIME):在运行时有效(即运行时保留)


为了更好的理解注解,我们来写一个注解,新建MyAnnotation.java文件如下:

package top.annotations;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface MyAnnotation {    int id();    String shuoming()default "";}

上面就是自定义注解的一般写法了,注意的几个点
1.@interface是注解的关键字
2.注解中的属性都要在最后加小括号,且默认是public。可以用default添加默认值
3.上述注解的作用对象是方法,作用时间是直到运行。

定义好了注解,再来看注解的使用:

public class Main {    @MyAnnotation(id=14)    public void f(){        System.out.print("f");    }}

在类的方法上方(或前方)可以写这个注解,因为id没有定义default值,所以必须要声明id的值。

到此为止,我们已经知道了jdk的自身7个注解都是干什么的了。并且利用元注解写了自定义注解,并进行使用了。那么问题来了,注解到底有啥作用?如果只是能看的话,用注释就可以了。注解的最大作用究竟在哪呢?
原来运行时注解,可以通过反射的方式获得。这种注解就能动态解析,并进行相应处理了。来看下注解的反射:

public class Main {    @MyAnnotation(id=14)    public void f(){        System.out.print("f");    }    public static void main(String[] a) throws NoSuchMethodException {               System.out.println(               Arrays.toString(Main.class.getMethod("f").getAnnotations()));    }}

打印:[@top.annotations.MyAnnotation(shuoming=, id=14)]
上面代码还是刚才那个类,添加一个main方法来打印f方法上方的所有注解,和之前讲的一样,getAnnotations()可以获取方法或字段或类的所有注解而getAnnotation(MyAnnotation.class)则可以获取形式为该注解的注解,如:

MyAnnotation annotation = Main.class.getMethod("f").getAnnotation(MyAnnotation.class);System.out.println(annotation.id());

则打印14。
判断是否含有某个注解:

System.out.println(    Main.class.getMethod("f").isAnnotationPresent(MyAnnotation.class));

打印true

小结:
到此我们学会了使用RUNTIME的注解,并用反射的形式获取注解和注解的属性值。我们可以利用这种注解做很多事情。比如权限控制,在方法上添加一条注解,运行时检测到注解是权限注解,并解析里面的权限等级。然后对比调用者等级是否够,如果够了才能执行该方法。注解形式类似:@Quanxian(level=3)。注解的作用远不止此。我们可以返回头看Hibernate的各种注解如@Entity @Table(name=xx)的动态解析的步骤。可能就是在配置文件中读到mapping的类,去找这个类判断是否有@Entity注解,如果没有就异常。然后解析是否有Table注解,如果没有则按照类名映射表名,如果有Table注解,则解析该注解的name属性,并以此为表名。

0 0
原创粉丝点击