【云计算】框架开发之Java注解解析
小标 2018-12-13 来源 : 阅读 583 评论 0

摘要:本文主要向大家介绍了【云计算】框架开发之Java注解解析,通过具体的内容向大家展现,希望对大家学习云计算有所帮助。

本文主要向大家介绍了【云计算】框架开发之Java注解解析,通过具体的内容向大家展现,希望对大家学习云计算有所帮助。


注解的好处:


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


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


3.(重点)刮目相看。

(但是怎么样才能让别人刮目相看呢?会用注解不是目的,最重要的是要使用自定义注解来解决问题。)

举个栗子:

如果面试的时候,你跟老板说你会使用注解,老板觉得你这个人还行;但是如果老板发现你会自定义注解解决问题,老板肯定就会眼前一亮。


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


一、Java中的常见注解


1)JDK注解

JDK注解一共分为三类:



JDK注解.png


案例:

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


public interface people {


 

public String name();


 

public int age();


 

public void work();


 

}


     


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


public class Child implements people {


 

@Override


 

public String name() {


 

return null;


 

}


 

@Override


 

public int age() {


 

return 0;


 

}


 

@Override


 

public void work() {


 

}


     


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


//public String name();


     


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


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


@Deprecated


 

public void work();


     


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


public class Test {


 

public void work() {


 

people people=new Child();


 

! people.work();


 

}


 

}


     


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


 

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)元注解:

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


三、自定义注解


我们分四步来解析自定义注解:

自定义注解的语法要求:
 

@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(),在使用时可以忽略成员名和赋值号(=)。

③.注解类可以没有成员,没有成员的注解称为标识注解。


元注解:


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

@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>,…)

案例:


@Description(desc="i am Color",author="boy",age=18)


 

public String Color() {


 

return "red";


 

}


     


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


解析注解

概念:

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


准备工作:



Description类.png



Child类.png


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


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类上面的注解。


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

    
 

//获取所有的方法


 

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

可以看到,我们成功的解析了方法上面的注解。



//另一种解析方法


 

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());


 

}


 

}


 

}


     


也可以得到上面的效果


          

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标大数据云计算大数据安全频道!


本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程