http://www.importnew.com/23564.html

注解的好处:

1.能够读懂别人写的代码,特别是框架相关的代码。

2.本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以使用一个或者多个注解来替代,这样就使得编程更加简洁,代码更加清晰。

3.(重点)刮目相看。
(但是怎么样才能让别人刮目相看呢?会用注解不是目的,最重要的是要使用自定义注解来解决问题。)
举个栗子:
如果面试的时候,你跟老板说你会使用注解,老板觉得你这个人还行;但是如果老板发现你会自定义注解解决问题,老板肯定就会眼前一亮。

注解这一概念是在java1.5版本提出的,说Java提供了一种原程序中的元素关联任何信息和任何元数据的途径的方法。

一、Java中的常见注解

1)JDK注解
JDK注解一共分为三类:

JDK注解.png

案例:
我们先新建一个接口people,如下:

1
2
3
4
5
public interface people {
    public String name();
    public int age();
    public void work();
}

然后再建一个类Child实现类people这个接口,并实现该类的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Child implements people {
    @Override
    public String name() {
        return null;
    }
 
    @Override
    public int age() {
        return 0;
    }
 
    @Override
    public void work() {
 
    }

看到这里,我们发现这里的所有方法都会加上一个@Override标记,它告诉我们,同时也告诉编译器我们的这些方法肯定覆盖了类people里面的方法的。假如说,我现在把类people里面的某一个方法注释掉:

1
//public String name();

再看类Child里面的name方法就会报错。这样,以后大家看到@Override的时候就能想到这个方法是覆盖了某个接口的方法的。

然后,我们回过头来看类people里面有一个work的方法。这里我们可以理解为人是要工作的,但是并不是所有的人都在工作,那么怎么办呢?如果说这个接口正在用,我们不能删除这个方法,这个时候我们就可以这样:

1
2
@Deprecated
public void work();

@Deprecated标记就表明这个方法已经过时了,在实际中,它又有什么样的应用场景呢?我们在建一个测试类:

1
2
3
4
5
6
public class Test {
    public void work() {
        people people=new Child();
!        people.work();
    }
}

这个时候我们会发现myeclipse会给一个警告,并且在work中间出现一个破折号,意思就是这个方法已经过时了。那么问题来了,虽然这个方法过时了,但是我们就是那么傲娇,一定要用它,怎么办呢?只需要这样:

1
2
3
4
5
6
7
public class Test {
    @SuppressWarnings("deprecation")
    public void work() {
        people people=new Child();
        people.work();
    }
}

这样我们就忽略了这个警告。@SuppressWarnings(“deprecation”)就表示我们忽略了deprecation这样的一个警告。

2)Java第三方注解

第三方注解.png

二、注解的分类

1)按照运行机制划分:
【源码注解→编译时注解→运行时注解】

源码注解:只在源码中存在,编译成.class文件就不存在了。

编译时注解:在源码和.class文件中都存在。像前面的@Override、@Deprecated、@SuppressWarnings,他们都属于编译时注解。

运行时注解:在运行阶段还起作用,甚至会影响运行逻辑的注解。像@Autowired自动注入的这样一种注解就属于运行时注解,它会在程序运行的时候把你的成员变量自动的注入进来。

2)按照来源划分:
【来自JDK的注解——来自第三方的注解——自定义注解】

3)元注解:
元注解是给注解进行注解,可以理解为注解的注解就是元注解。

三、自定义注解

我们分四步来解析自定义注解:
自定义注解的语法要求:

1
2
3
4
5
6
7
8
9
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
    String desc();
    String author();
    int age() default 18;
}

首先我们要明确这不是一个接口,它是使用@interface关键字定义的一个注解。
然后我们看下面的几个方法,String desc();虽然它很类似于接口里面的方法,其实它在注解里面只是一个成员变量(成员以无参无异常的方式声明),int age() default 18;(成员变量可以用default指定一个默认值的)。
最后我们要知道:
①.成员类型是受限制的,合法的类型包括基本的数据类型以及String,Class,Annotation,Enumeration等。
②.如果注解只有一个成员,则成员名必须取名为value(),在使用时可以忽略成员名和赋值号(=)。
③.注解类可以没有成员,没有成员的注解称为标识注解。

元注解:

有没有发现上面那段代码有一个没有说呢?没错,它们就是我们所说的元注解:

1
2
3
4
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented

我们先看第一行:@Target是这个注解的作用域,ElementType.METHOD是这个注解的作用域的列表,METHOD是方法声明,除此之外,还有:
CONSTRUCTOR(构造方法声明),FIELD(字段声明),LOCAL VARIABLE(局部变量声明),METHOD(方法声明),PACKAGE(包声明),PARAMETER(参数声明),TYPE(类接口)

第二行:@Retention是它的生命周期,前面不是说注解按照运行机制有一个分类嘛,RUNTIME就是在运行时存在,可以通过反射读取。除此之外,还有:
SOURCE(只在源码显示,编译时丢弃),CLASS(编译时记录到class中,运行时忽略),RUNTIME(运行时存在,可以通过反射读取)

第三行:@Inherited是一个标识性的元注解,它允许子注解继承它。

第四行:@Documented,生成javadoc时会包含注解。

使用自定义注解:
使用注解的语法:
@<注解名>(<成员名1>=<成员值1>,<成员名1>=<成员值1>,…)
案例:

1
2
3
4
@Description(desc="i am Color",author="boy",age=18)
public String Color() {
    return "red";
}

这里的Description是我们刚才在自定义注解语法要求里面定义的注解噢,然后我们可以给它的每一个成员变量赋值,注意数据类型。值得注意的是,因为我们前面定义的作用域是在方法和类接口上,所以这个注解在Color()方法上使用是没问题的。

解析注解
概念:
通过反射获取类 、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑。

准备工作:

Description类.png

Child类.png

接下来,我们就开始测试了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ParseAnn {
    public static void main(String[] args) {
        try {
            // 使用类加载器加载类
            Class c = Class.forName("com.test.Child");
            // 找到类上面的注解
            boolean isExist = c.isAnnotationPresent(Description.class);
            // 上面的这个方法是用这个类来判断这个类是否存在Description这样的一个注解
            if (isExist) {
                // 拿到注解实例,解析类上面的注解
                Description d = (Description) c.getAnnotation(Description.class);
                System.out.println(d.value());
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出的结果:
i am class annotation
可以看到,我们成功的解析了Child类上面的注解。

接下来,我们继续解析方法上的注解:

1
2
3
4
5
6
7
8
9
10
//获取所有的方法
Method[] ms = c.getMethods();
// 遍历所有的方法
for (Method m : ms) {
    boolean isExist1 = m.isAnnotationPresent(Description.class);
    if (isExist1) {
        Description d1=m.getAnnotation(Description.class);
        System.out.println(d1.value());
    }
}

输出的结果:
i am class annotation
i am method annotation
可以看到,我们成功的解析了方法上面的注解。

1
2
3
4
5
6
7
8
9
10
11
12
//另一种解析方法
for (Method m : ms) {
    //拿到方法上的所有的注解
    Annotation[] as=m.getAnnotations();
    for (Annotation a : as) {
        //用二元操作符判断a是否是Description的实例
        if (a instanceof Description) {
            Description d=(Description) a;
            System.out.println(d.value());
        }
    }
}

也可以得到上面的效果。

此时,如果把Description类里面的元注解改一下,比如:
@Retention(RetentionPolicy.RUNTIME)→@Retention(RetentionPolicy.SOURCE),再运行程序,结果会成怎样呢?如果改成CLASS呢?读者们要不要试一试?

java 注解 总结的更多相关文章

  1. Java注解

    Java注解其实是代码里的特殊标记,使用其他工具可以对其进行处理.注解是一种元数据,起到了描述.配置的作用,生成文档,所有的注解都隐式地扩展自java.lang.annotation.Annotati ...

  2. 19.Java 注解

    19.Java注解 1.Java内置注解----注解代码 @Deprecated                                    //不推荐使用的过时方法 @Deprecated ...

  3. Java注解入门

    注解的分类   按运行机制分:   源码注解:只在源码中存在,编译后不存在 编译时注解:源码和编译后的class文件都存在(如@Override,@Deprecated,@SuppressWarnin ...

  4. java注解(Annotation)解析

    注解(Annotation)在java中应用非常广泛.它既能帮助我们在编码中减少错误,(比如最常见的Override注解),还可以帮助我们减少各种xml文件的配置,比如定义AOP切面用@AspectJ ...

  5. JAVA 注解的几大作用及使用方法详解

    JAVA 注解的几大作用及使用方法详解 (2013-01-22 15:13:04) 转载▼ 标签: java 注解 杂谈 分类: Java java 注解,从名字上看是注释,解释.但功能却不仅仅是注释 ...

  6. attilax.java 注解的本质and 使用最佳实践(3)O7

    attilax.java 注解的本质and 使用最佳实践(3)O7 1. 定义pojo 1 2. 建立注解By eclipse tps 1 3. 注解参数的可支持数据类型: 2 4. 注解处理器 2 ...

  7. paip.java 注解的详细使用代码

    paip.java 注解的详细使用代码 作者Attilax 艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.net/att ...

  8. JAVA 注解的几大作用及使用方法详解【转】

    java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解 ...

  9. 框架基础——全面解析Java注解

    为什么学习注解? 学习注解有什么好处? 学完能做什么? 答:1. 能够读懂别人写的代码,特别是框架相关的代码: 2. 让编程更加简洁,代码更加清晰: 3. 让别人高看一眼. spring.mybati ...

  10. Java注解配置

    Java注解是附加在代码中的一些元信息,用于一些工具在编译.运行时进行解析和使用,起到说明.配置的功能.注解不会也不能影响代码的实际逻辑,仅仅起到辅助性的作用.包含在 java.lang.annota ...

随机推荐

  1. 假装会python--爬取贴吧正文

    贴吧的老历史想存下来,强行python爬取一波 队友太强,躺好别动,偶尔做点副业 假装会python 基本流程: 1.爬取页面,获取页面的html源码 2.分析源码 通过正则表达式 匹配到想要的内容 ...

  2. 利用CSS3实现简书中点击“喜欢”时的动画

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. Jenkins 01——简介

    Jenkins是一个开源软件项目,一个可扩展的持续集成引擎.旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. 持续集成是一种开发实践,需要开发人员定期将代码集成到共享存储库中.这个概念意在消 ...

  4. AngularJS入门基础——控制器

    AngularJS中的控制器是一个函数,用来向视图的作用域添加额外的功能.我们用它来给作用域对象设置初始状态,并添加自定义行为. AngularJS同其他JavaScript框架最主要的一个区别就是, ...

  5. 20155224 2016-2017-2 《Java程序设计》第6周学习总结

    20155224 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 Thread线程: 定义某线程后,要有 xxx.stard(); Thread.sleep( ...

  6. 阿里云OSS 中文名称地址不对

    oss中将该中文名称重命名.再输入一次

  7. 常用的C#编译命令

    使用 csc.exe 实现命令行生成 作为一个半路出家的非计算机专业出身的前端码农,最近对C#很感兴趣,原因如下: 1.希望通过学习C#能熟悉一下windows系统和一些概念,例如:windows服务 ...

  8. JS判断客户浏览器是否是IE8浏览器、jQuery判断浏览器内核

    今天在使用encharts的时候由于要兼容IE8,所以最终决定在非IE8浏览器使用encharts,在IE8使用amcharts.于是需要使用JS判断使用的浏览器版本: function IEVers ...

  9. mybatis入门程序-(二)

    1. 添加配置文件 log4j.properties # Global logging configuration #开发环境下日志级别设置成DEBUG,生产环境设置成info或者error log4 ...

  10. Ansible Tower系列 四(使用tower执行一个命令)【转】

    在主机清单页面中,选择一个主机清单,进入后,选择hosts里的主机 Paste_Image.png 点击 RUN COMMANDS MODULE 选择 commandARGUMENTS 填写 ifco ...