1、首先了解注解是什么,参考如下文章,同时了解自定义注解。
在Java中,配置文件(Configuration Files)是注解出现之前用于传递元数据的另一种方式。配置文件是一种将程序配置信息存储在外部文件中的方法,以便在程序运行时读取和使用这些配置信息。
在一些情况下,配置文件可以用于传递元数据,例如在配置框架、应用程序设置、数据库连接等方面。通过读取配置文件,程序可以获取一些必要的信息,从而影响其行为和功能。
然而,配置文件也有一些局限性,例如:
格式不统一: 配置文件的格式可能因文件类型、工具、框架而异,导致解析和处理变得复杂。
易于出错: 配置文件容易出现错误,例如拼写错误、格式错误等,这些错误可能难以定位和修复。
无法与代码关联: 配置文件通常与代码分离,难以直接与代码关联,使得代码和配置之间的联系不够紧密。
注解的引入解决了这些问题,使得元数据能够更紧密地与代码关联,更加可读和可维护。通过在代码中使用注解,开发者可以在代码级别上提供元数据,从而增加了代码的可读性、维护性和灵活性。这与配置文件的思路相似,但注解能够更加直接地嵌入到代码中,并且在编译期和运行期都能够被直接处理。
注解(Annotation)是一种元数据,用于为程序代码提供信息,不会直接影响程序的执行,但可以提供编译器、工具和框架额外的信息。注解最早在Java SE 5.0版本中引入,它们为开发者提供了一种在源代码中添加元数据的方式,以便在编译期、运行期或者其他工具中处理这些信息。注解的引入使得代码的描述更加丰富,同时也方便了代码的生成、分析和管理。
自定义注解的编写:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 定义一个自定义注解
(RetentionPolicy.RUNTIME) // 指定注解保留到运行时
(ElementType.METHOD) // 指定注解适用于方法
public MyCustomAnnotation {
String value(); // 声明注解成员
}
在这个示例中,我们创建了一个名为 MyCustomAnnotation 的自定义注解,它具有一个成员 value。@Retention 注解指定了注解的保留策略,这里我们选择在运行时保留,以便在运行期间访问注解信息。@Target 注解指定了注解可以应用的目标,这里我们指定了它适用于方法。
你可以在代码中使用自定义注解,并为注解成员提供值:
public class MyClass {
(value = "Hello, Custom Annotation!")
public void myMethod() {
// 方法内容
}
}
在实际应用中,你可以通过反射来获取注解信息并根据注解信息进行不同的处理。这种方式在编写框架、库、测试工具等方面非常有用。
请注意,虽然这只是一个简单的例子,但自定义注解在实际应用中可以非常强大。你可以根据实际需求定义更复杂的自定义注解,并在项目中使用它们来提供更多的元数据信息。
在Java中,配置文件(Configuration Files)是注解出现之前用于传递元数据的另一种方式。配置文件是一种将程序配置信息存储在外部文件中的方法,以便在程序运行时读取和使用这些配置信息。
在一些情况下,配置文件可以用于传递元数据,例如在配置框架、应用程序设置、数据库连接等方面。通过读取配置文件,程序可以获取一些必要的信息,从而影响其行为和功能。
然而,配置文件也有一些局限性,例如:
格式不统一: 配置文件的格式可能因文件类型、工具、框架而异,导致解析和处理变得复杂。
易于出错: 配置文件容易出现错误,例如拼写错误、格式错误等,这些错误可能难以定位和修复。
无法与代码关联: 配置文件通常与代码分离,难以直接与代码关联,使得代码和配置之间的联系不够紧密。
注解的引入解决了这些问题,使得元数据能够更紧密地与代码关联,更加可读和可维护。通过在代码中使用注解,开发者可以在代码级别上提供元数据,从而增加了代码的可读性、维护性和灵活性。这与配置文件的思路相似,但注解能够更加直接地嵌入到代码中,并且在编译期和运行期都能够被直接处理。
在Java中,你可以通过创建自定义注解来为代码添加元数据,这可以帮助你在编写工具、框架或库时提供更多的信息。下面是一个简单的示例,展示如何编写一个自定义注解:
2、完全手写一个自定义注解(遍历版和map版)
公共部分代码
package LengthImpl1;
import lombok.Data;
/**
* @ClassName Person
* @Description TODO
* @Author zy
* @Date 2022/10/14 18:56
* @Version 1.0
*/
@Data
public class Person {
//声明字符串类型的属性id
private String id;
@Length(min=3, max =8, errorMsg = "姓名长度必须3-8之间")
private String name;
private Integer age;
}
package LengthImpl1;
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)
//自定义注解,注解名字是Length
public @interface Length {
// 允许的字符串长度最小值
int min();
// 的允许字符串长度最大值
int max();
// 自定义错误提示
String errorMsg();
}
遍历版
package LengthImp;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* @BelongsProject: JAVAtest
* @BelongsPackage: LengthImp
* @Author: GuoYuan.Zhao
* @CreateTime: 2023-02-25 11:38
* @Description: TODO
* @Version: 1.0
*/
public class Client {
public static void main(String[] args) throws IOException, NoSuchFieldException, ClassNotFoundException {
LengthImpl length = new LengthImpl();
length.traverseAllFields();
System.out.println(length.min());
System.out.println(length.max());
System.out.println(length.errorMsg());
}
}
package LengthImp;
import java.io.*;
import java.lang.annotation.Annotation;
import java.util.*;
/**
* @BelongsProject: 09_annotation_source
* @BelongsPackage:
* @Author: 赵媛
* @Description: 描述什么人干什么事儿
* @CreateTime: 2023-02-21 11:10
* @Version: 1.0
*/
public class LengthImpl implements Length {
@Override
public int min() {
return Integer.valueOf(minInterger);
}
@Override
public int max() {
return Integer.valueOf(maxInteger);
}
@Override
public String errorMsg() {
return errorInfo;
}
String maxInteger ;
//获取min后边的数值
String minInterger ;
//获取error后边的字符串
String errorInfo ;
public void traverseAllFields() throws IOException, ClassNotFoundException, NoSuchFieldException {
String fileName = "";
String methodName = "";
List<String> lineLists = new ArrayList<>();
String lineListsYes ;
int index = 0;
Scanner scanner = new Scanner(System.in);
System.out.println("请输入文件路径");
fileName = scanner.next();
System.out.println("请输入要查阅的属性名称");
methodName = scanner.next();
//首先声明一个list放置每行的文本
Scanner scannerLine = new Scanner(new FileReader(fileName));
while (scannerLine.hasNextLine()){ //按行读取字符串
String line = (scannerLine.nextLine());
lineLists.add(line);
}
// System.out.println(lineLists);
//遍历这个list里边的值,哪一行里边有属性name关键字
for(String everyLineString : lineLists){
if(everyLineString.contains(methodName)){
//获取当前索引
index = lineLists.indexOf(everyLineString);
}
}
//找到上一行的位置
lineListsYes = lineLists.get(index-1);
// System.out.println(lineListsYes);
//读取length后的关键字,可以进行直接输出,也可以放到map里边
String annotationValue = lineListsYes.replace("(", ",");
String annotationValue1 = annotationValue.replace(")", ",");
String[] fields = annotationValue1.split(",");
for (int i = 0; i < fields.length; i++) {
if(fields[i].contains("min")){
minInterger = fields[i].split("=")[1];
}
if(fields[i].contains("max")){
maxInteger = fields[i].split("=")[1];
}
if(fields[i].contains("errorMsg")){
errorInfo = fields[i].split("=")[1];
}
}
}
@Override
public Class<? extends Annotation> annotationType() {
return null;
}
}
map版
package LengthImpl1;
import java.io.IOException;
/**
* @BelongsProject: JAVAtest
* @BelongsPackage: LengthImp
* @Author: GuoYuan.Zhao
* @CreateTime: 2023-02-25 11:38
* @Description: TODO
* @Version: 1.0
*/
public class Client {
public static void main(String[] args) throws IOException, NoSuchFieldException, ClassNotFoundException {
// LengthImpl length = new LengthImpl();
// length.traverseAllFields();
MapImpl map = new MapImpl();
map.readFileInfo();
// System.out.println(length.min());
// System.out.println(length.max());
// System.out.println(length.errorMsg());
System.out.println(map.min());
System.out.println(map.max());
System.out.println(map.errorMsg());
}
}
package LengthImpl1;
import javassist.bytecode.AttributeInfo;
import javassist.bytecode.ClassFile;
import javassist.bytecode.FieldInfo;
import java.io.*;
import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @BelongsProject: JAVAtest
* @BelongsPackage: LengthImpl1
* @Author: GuoYuan.Zhao
* @CreateTime: 2023-02-26 17:21
* @Description: TODO
* @Version: 1.0
*/
public class MapImpl implements Length {
@Override
public int min() {
// String min = this.readFile("min");
// System.out.println("最小值为:"+min);
// return Integer.valueOf(min) ;
String minValue = this.getMethedValue(Thread.currentThread().getStackTrace()[1].getMethodName());
return Integer.valueOf(minValue);
}
@Override
public int max() {
// String max = this.readFile("max");
// System.out.println("最大值为:"+max);
// return Integer.valueOf(max) ;
String maxValue = this.getMethedValue(Thread.currentThread().getStackTrace()[1].getMethodName());
return Integer.valueOf(maxValue);
}
@Override
public String errorMsg() {
// String errorMessage = this.readFile("errorMsg");
// System.out.println("错误信息:"+ errorMessage);
// return errorMessage;
String errorMsgValue = this.getMethedValue(Thread.currentThread().getStackTrace()[1].getMethodName());
return errorMsgValue;
}
@Override
public Class<? extends Annotation> annotationType() {
return null;
}
boolean state=true;
private String getMethedValue(String name){
if (state==true){
state=false;
methedValue= this.readFileInfo();
}
if(name.equals("errorMsg")){
System.out.println("错误信息:"+ methedValue.get(name));
return methedValue.get(name);
}else if(name.equals("min")){
return methedValue.get(name);
}else if(name.equals("max")){
System.out.println("最大值为:"+methedValue.get(name));
return methedValue.get(name);
}
return null;
}
Map<String,String> methedValue = new HashMap<>();
public Map<String, String> readFileInfo() {
try{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入要读取文件的路径");
String fileName=br.readLine();
DataInputStream csanner = new DataInputStream(new FileInputStream(new File(fileName)));
ClassFile classFile = new ClassFile(csanner);
List<FieldInfo> fieldsList = classFile.getFields();
for (FieldInfo field:fieldsList){
for (AttributeInfo attributeInfo : field.getAttributes()) {
System.out.println(attributeInfo);
String annotationValue = attributeInfo.toString().replace("(", ",");
String annotationValue1 = annotationValue.replace(")", ",");
String[] fields = annotationValue1.split(",");
for (int i = 1; i < fields.length; i++) {
String[] fieldSplit = fields[i].split("=");
methedValue.put(fieldSplit[0].trim(),fieldSplit[1].trim());
System.out.println(methedValue);
}
}
}
}catch (Exception e){
System.out.println("获取文件失败"+e);
}
return methedValue;
}
}