请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

Java注解入门

[复制链接]
查看: 99|回复: 0

2万

主题

2万

帖子

7万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
70839
发表于 2020-1-17 02:44 | 显示全部楼层 |阅读模式
  自JDK1.5引入注解后,他就成为了Java编程说话严重的组成部分,在斥地进程中,我们也经常用到@Override、@ToString等这样的注解。在这篇文章中,将先容什么是注解、为什么援用注解、它是怎样工作的、怎样编写自界说注解、以及怎样测试自界说注解。 一、什么是注解?  用一个词便可以描摹注解,那就是元数据,即一种描摹数据的数据,可以大白为描摹数据的一种标志。如以下代码:
  1. @Overridepublic void doSomething() {    System.out.println("复写了父类doSomething()!)");}
复制代码
  总的来说,Annotation(注解)是一种利用于类、方式、参数、变量、机关器及包声明中的出格修饰符;Java注解是附加在代码中的一些元信息,用于一些工具在编译、运转时举行分解和操纵,起到分析、设置的功用。注解不会也不能影响代码的现实逻辑,仅仅起到帮助性的感化。包含在 java.lang.annotation 包中;它是一种由JSR-175标准挑选用来描摹元数据的一种工具。 二、为什么引入注解?  操纵Annotation注解之前,XML被普遍的利用于描摹元数据。随着项方针斥地与保护,XML的表示越来越糟糕,此时,人们希望在一些场所操纵紧耦合的方式举行代码描摹。固然,并不是说XML方式欠好,两者各有上风:假如你想为利用设备很多的常量或参数,这类情况下,XML是一个很好的挑选,由于它不会同特定的代码相连;假如你想对代码举行设置分析、编译提醒等时,那末操纵Annotation注解会更好一些。  注解的用处:  1、天生文档。这是最多见的,也是java 最早供给的注解。常用的有@param @return 等  2、跟踪代码依靠性,实现更换设置文件功用。比如Dagger 2依靠注入,未来java斥地,将大量注解设置,具有很大用处,比如现在的Springboot框架;  3、在编译时举行格式检查。如@override 放在方式前,假如你这个方式并不是覆盖了超类方式,则编译时就能检查出。斥地时我们可以按照它的用处来权衡操纵XML方式与操纵Annotation注解的利弊来挑选能否操纵Annotation注解。(参考:https://blog.csdn.net/PORSCHE_GT3RS/article/details/80304701 ) 三、注解是怎样工作的?  注解本质是一个继续了Annotation的出格接口,其具体实现类是Java运转时天生的静态代理类。而我们经过反射获得注解时,返回的是Java运转时天生的静态代理工具$Proxy。经过代理工具挪用自界说注解(接口)的方式,会终极挪用AnnotationInvocationHandler的invoke方式。该方式会从memberValues这个Map中索引出对应的值。而memberValues的根源是Java常量池。关于更具体的了解可以参考这篇blog:https://blog.csdn.net/lylwo317/article/details/52163304。在这篇文章中具体先容了怎样检察与获得生产的代理工具的字节码文件,从而得悉生产的代理工具的具体的代码实现。 四、怎样编写自界说注解  编写自界说的注解之前,首先得了解注解相关的底子概念——元注解。  元注解,专门注解其他的注解(在自界说注解的时辰,必要操纵到元注解),起到指定注解(自界说注解)的感化范围、生命周期等感化。java.lang.annotation供给了四种元注解:    1)@Documented——注解能否将包含在JavaDoc中,一个简单的Annotations标志注解,表示能否将注解信息增加在java文档中    2)@Retention ——什么时辰操纵该注解,界说该注解的生命周期    3)@Target? ——注解用于什么地方。假如不大白指出,该注解可以放在任何地方。以下是一些可用的参数。必要分析的是:属性的注解是兼容的,假如你想给7个属性都增加注解,仅仅断根一个属性,那末你必要在界说target包含全数的属性。        ElementType.TYPE:用于描摹类、接口或enum声明        ElementType.FIELD:用于描摹实例变量        ElementType.METHOD:用于描摹实例方式        ElementType.PARAMETER:用于描摹实例方式参数        ElementType.CONSTRUCTOR:用于描摹实例的机关函数        ElementType.LOCAL_VARIABLE:用于描摹部分变量        ElementType.ANNOTATION_TYPE 另一个表白        ElementType.PACKAGE 用于记载java文件的package信息    4)@Inherited —— 能否答应子类继续该注解  可是从JDK1.8起头,又新增加了两个元注解:    @Native——指示可从本机代码援用界说常量值的字段。    @Repeatable——用于指示其声明(元)表白的表白典范是可反复的。   下面我们起头编写自界说注解。语法以下,操纵@interface来表白声明的是一个注解
  1. public @interface 注解称号 {    //String weather() default "";//注解中可以没有属性,而且在注解中属性是以方式的形式存在}
复制代码
  可是,编写注解的时辰仅仅做到如上代码的样子还远远不够,凡是,还必要为他们指定注解的感化范围、生命周期等,这时辰就必要用到元注解对我们界说的注解举行注解(标识分析)了。
  1. import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; @Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface WeatherAnnotation {    String weather() default "";}
复制代码
  以上注解经过ElementType.FIELD限制了该注解只能标识属性,经过RetentionPolicy.RUNTIME指定了注解的生命周期——代码运转时生效,自界说注解底子上都是操纵该罗列字段声明其生命周期。接下来,起头编写测试注解的代码:
  1. package com.wyfx.nio.annotation; public class Today {    @WeatherAnnotation(weather="hello,本日是晴天")    private String dayWeather;     public String getDayWeather() {        return dayWeather;    }     public void setDayWeather(String dayWeather) {        this.dayWeather = dayWeather;    }     @Override    public String toString() {        return "Today{" +                "dayWeather='" + dayWeather + '\'' +                '}';    }}
复制代码
  1. import java.lang.reflect.Field;public class Test {    public static void main(String[] args){        /*Annotation annotations=new Today().getClass().getAnnotation(WeatherAnnotation.class);*/        try {            Class aClass=Class.forName("com.wyfx.nio.annotation.Today");            Field[] fields= aClass.getDeclaredFields();            String weather="";            for (Field field : fields) {                if(field.isAnnotationPresent(WeatherAnnotation.class)){                    WeatherAnnotation weatherAnnotation=field.getAnnotation(WeatherAnnotation.class);                    weather= weatherAnnotation.weather();                }            }            System.out.println("--annotation---:"+weather);        }catch (Exception e){            e.printStackTrace();        }    }}
复制代码
  以上代码顺遂打印出“hello,本日是晴天”,分析自界说注解成功了,值得留意的是,注解的感化域是属性,所以在经过反射举行测试的时辰,必须在Field的底子上去判定能否是Annotation接口的子类(field.isAnnotationPresent(),然后获得注解子类工具。

免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 淄博新闻网-淄博日报 淄博晚报 淄博财经新报 掌中淄博 淄博专业新闻资讯发布网站 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表