centos8安装教程python注解annotation_Annotation注解(⼀)-基础
这篇博客,主要讲解关于注解的⼀些基本知识,包括注解的概念、分类、作⽤,常见注解的定义及其解析⽅式等。
Annotation的概念
1. 概念
关于Annotation注解的概念,我们可以看下官⽅的解释:
Annotations, a form of metadata;
docker是什么意思英语provide data about a program that is not part of the program itself.
Annotations have no direct effect on the operation of the code they annotate
Annotation注解是Java中的⼀种元数据,它可以往源代码中添加额外的数据,并且对注解的代码⽆直接影响;包名、类、成员⽅法、成员属性、参数都可以被注解。
2. 作⽤
注解可以让我们的代码更加简洁,并且增加代码的复⽤性,避免冗余代码。
如果细分起来,注解主要有3个作⽤:
编译时标记:在编译时,通过标记代码,来提⽰信息、检查错误
编译时处理:在编译时,通过构建代码,来动态⽣成⼀些额外的代码、或者Java/XML等⽂件
运⾏时处理:在运⾏时,我们可以动态的获取注解信息
3. 分类
1. 标准Annotation
标准Annotation是指Java⾃带的Annotation。
eg:@Override[重写]、@Deprecated[不⿎励使⽤]、@SuppressWarnings[忽略警告]等。
2. 元Annotation
元Annotation是指注解Annotation的Annotation。
eg:@Retention, @Target, @Inherited, @Documented等。
3. ⾃定义Annotation
我们可以利⽤元Annotation来⾃定义⼀些⾃⼰的Annotation。
元Annotation
元Annotation是指注解Annotation的Annotation。
@Documented:Annotation是否会保存到JavaDoc⽂档中
@Inherited:Annotation是否可以被继承,默认是false
@Target(ElementType[] types):Annotation可以⽤来注解哪些元素
ElementType:元素类型,⽐如类、⽅法、变量、参数等
@Retention(RetentionPolicy ploicy):Annotation的保留策略
RetentionPolicy.SOURCE:Annotation仅保留在java源码中
-
⼤都为Mark Annotation,做⼀个警⽰、校验的作⽤
RetentionPolicy.CLASS:Annotation保留在java源码、class⽂件中
- 默认的保留策略,⼀般配合Processor注解处理器,在构建时动态⽣成代码
RetentionPolicy.RUNTIME:Annotation保留在java源码、class⽂件、运⾏时
- 与CLASS的区别是,这类Annotation在运⾏时会被加载到JVM中,因此我们可以在程序运⾏的过程中动态获取到Annotation的相关信息⾃定义Annotation
我们先来看⼀下⼀个最为基础的Annotation⽰例代码(这是⼀个⾃动⽣成类头信息的⼀个注解)
调⽤
@ClassInfo (
author = "xzqbetter@163",
date = "11/17/2017",
currentRevision = 6,
reviewers = {"Alice", "Bob", "Cindy"} // Note array notation
)
public class Test1 {
// class code goes here
}
定义
public @interface ClassInfo {
String author();
String date();
int currentRevision() default 1;
String[] reviewers(); // Note use of array
}
解释
1.注解的定义:可以看到,我们利⽤@interface,定义了⼀个注解类,之后就可以在代码中使⽤这个注解
@interface是interface的⼀种变异形式
2.参数的定义:在注解类内部,我们声明了很多抽象⽅法,来定义注解所需的参数
对应关系:⽅法名 - 参数名,⽅法的返回值 - 参数类型
一建报名资格条件返回值的限制:只能是基本类型、String、Class、Enumeration、Annotation及其⼀维数组
⽅法的限制:这些⽅法没有⽅法体、没有参数、不能抛异常,并且只能⽤public abstract进⾏修饰
可以⽤default来指定默认值
如果只有⼀个参数,可以⽤value()代替(在使⽤的时候⽆需写参数名)
可以利⽤classInfo.author()来获取参数值
解析Annotation
完成⾃定义Annotation后,我们还需要知道,针对这些注解,我们要做哪些相关的处理,这就涉及到了Annotation的解析操作。解析Annotation,通常分为:对运⾏时Annotation的解析、对编译时Annotation的解析;
解析Annotation,其实就是如何从代码中到Annotation,通常我们的做法是:
⽤反射的⽅式获取Annotation,运⾏时Annotation的解析⽅式
借助apt⼯具获取Annotation,编译时Annotation的解析⽅式
另外如果我们需要⽣成额外的代码、⽂件,则还需要借助JavaPoet API
反射
反射的解析⽅式,通常运⽤在运⾏时Annotation的解析。
反射是指:利⽤Class、Field、Method、Construct等reflect对象,获取Annotation:
field.isAnnotationPresent(Annotation.class):是否存在该Annotationpython基础代码注释
这样,我们就可以在程序运⾏过程中,动态的获取Annotation的信息。
借助反射进⾏解析,这在⼀定程度上会影响程序性能
APT⼯具
概念
APT:是⼀个注解处理⼯具 Annotation Processing Tool
作⽤:利⽤apt,我们可以到源代中的注解,并根据注解做相应的处理
根据注解,⽣成额外的源⽂件或其他⽂件
编译⽣成的源⽂件和原来的源⽂件,⼀起⽣成class⽂件
利⽤APT,在编译时⽣成额外的代码,不会影响性能,只是影响项⽬构建的速度
Android Studio配置
使⽤apt⼯具前,需要对gradle做⼀些基本的配置:
1.在project的adle中,添加apt的依赖
dependencies {
classpath 'adle.plugins:android-apt:1.8'
}
2.在module的adle中,使⽤apt插件
apply plugin: 'bedankt.android-apt'
JavaPoet
JavaPoet:是⼀个⾃动⽣成Java代码的Java API。
在使⽤前,我们需要导⼊相关的依赖:
compile 'com.squareup:javapoet:1.7.0'
JavaPoet主要有以下⼏个关键类:
JavaFile:⽣成Java⽂件
TypeSpec:定义类
MethodSpec:定义⽅法
MethodSpec
MethodSpec主要⽤来定义⽅法。
MethodSpec mainSpec = hodBuilder("main") // ⽅法名
.addModifiers(Modifier.PUBLIC, Modifier.STATIC) // 修饰符
.addParameter(String[].class, "args") // 参数
.returns(TypeName.VOID) // 返回值
.
addStatement("$T.out.println($S)", System.class, "Hello,World!!") // 具体代码
.build();
// 添加代码的⽅法
mainBuilder.addCode("System.out.println(\"Hello,World!\")");
mainBuilder.addStatement("$T.out.println($S)",System.class,"Hello, World!");
mainBuilder.addStatement("activity.$L= ($T) activity.findViewById($L)",
element, (member.asType()), injectViewAnno.value() );
// 这⾥的element表⽰⼀个成员变量, injectViewAnno是⼀个Annotation, value是注解的参数值⽅法名:methodBuilder()
修饰符:addModifiers(Modifier)
返回值:return(TypeName)
参数:addParameter(Class, name)
添加代码:addStatement末尾会⾃动添加换⾏符,addCode末位不会⾃动添加换⾏符
-$T:表⽰需要import的类
-$S:表⽰字符串,会⾃动添加双引号
-$L:表⽰变量,不带双引号
TypeSpec
TypeSpec主要⽤来定义类。
// 外部类
TypeSpec typeSpec = TypeSpec.classBuilder("HelloWorld") // 类名
.addModifiers(Modifier.PUBLIC, Modifier.FINAL) // 修饰符
.addMethod(mainSpec) // ⽅法
.build();
/
/ 内部类
TypeSpec typeSpec = TypeSpec.anonymousClassBuilder("innerClass") // 内部类的类名
.addSuperinterface(OutClass.class) // 外部类的Class
.build();
JavaFile
JavaFile是真正⽣成Java⽂件的核⼼类。
try {
JavaFile javaFile = JavaFile.builder("ample.seven", typeSpec).build(); // 指定包名+类javaFile.Filer()); // 固定写法
} catch (IOException e) {
e.printStackTrace();
}
运⾏时Annotation
运⾏时Annotation,是指@Retention为RetentionPolicy.RUNTIME的注解。
对于这类注解,我们通常配合反射进⾏解析。
运⾏时Annotation的解析,需要借助反射进⾏解析,这在⼀定程度上会影响程序性能。
早期的依赖注⼊框架,⼤都属于运⾏时处理。
⽰例代码
public static void main(String[] args) {
try {
Class clazz = Class.forName("ample.Runtime");
for (Method method : Methods()) {
MethodAnno methodAnno = Annotation(
MethodAnno.class);
if (methodAnno != null) {
linux系统界面关机System.out.println("method name:" + Name());
System.out.println("method author:" + methodAnno.author());
System.out.println("method version:" + methodAnno.version());
System.out.println("method date:" + methodAnno.date());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
编译时Annotationjavareplace函数怎么用

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。