昆山设计网站的公司哈尔滨关键词优化排行
news/
2025/10/8 10:31:37/
文章来源:
昆山设计网站的公司,哈尔滨关键词优化排行,上海关键词优化方法,深圳查询建设项目规划的网站1、Lombok简介
作为java的忠实粉丝#xff0c;但也不得不承认#xff0c;java是一门比较啰嗦的语言#xff0c;很多代码的编写远不如其他静态语言方便#xff0c;更别说跟脚本语言比较了。
因此#xff0c;lombok应运而生。
Lombok是一种工具库#xff0c;它提供了一组…1、Lombok简介
作为java的忠实粉丝但也不得不承认java是一门比较啰嗦的语言很多代码的编写远不如其他静态语言方便更别说跟脚本语言比较了。
因此lombok应运而生。
Lombok是一种工具库它提供了一组注解用于简化Java代码的编写。它的主要目标是通过自动生成代码来减少样板代码的数量从而提高开发人员的生产力。
使用Lombok开发人员可以通过添加注解来自动生成getter和setter方法、构造函数、equals和hashCode方法以及其他常见的样板代码。此外Lombok还提供了一些其他的注解可以自动生成日志记录、单例模式、Builder模式等。
Lombok的使用非常简单只需在类或字段上添加注解即可。在编译时Lombok会自动生成相应的代码并将其写入源代码中。这意味着生成的代码会被编译器视为原始代码的一部分从而允许开发人员在使用生成的代码时获得代码补全和其他IDE功能的支持。
总的来说Lombok是一个能够减少Java代码冗余的有用工具它可以帮助开发人员更高效地编写代码提高开发速度和代码质量。
项目地址 lombok官网
2、Lombok原理
用了那么久lombok就是觉得写代码方便很多了但它底层的原理是什么呢
Lombok 的核心原理是在编译时通过注解处理器Annotation Processor来操作抽象语法树Abstract Syntax Tree, AST从而扩展 Java 编译器的功能。
2.1.Lombok工作原理
Lombok 的工作原理主要包括以下几个步骤 注解定义 Lombok 定义了一系列注解这些注解可以被应用于 Java 类、方法、字段等元素上。 注解处理器 Lombok 包含了一个或多个注解处理器这些处理器在编译时期被触发。当处理器检测到 Lombok 注解时它会根据注解的配置生成相应的代码。 编译时代码生成 使用 Lombok 注解的 Java 类在编译时Lombok 的注解处理器会读取注解信息并根据这些信息生成额外的 Java 代码。例如当在字段上使用 Getter 和 Setter 注解时Lombok 会生成对应的 getter 和 setter 方法。 AST 操作 Lombok 通过操作 Java 源文件的 AST 来插入生成的代码。AST 是源代码的树状结构表示Lombok 通过修改 AST 来实现代码的自动添加。 源代码注入 生成的代码会被注入到源文件中通常作为单独的文件或在原有文件中以特殊的方式添加以便编译器能够识别并编译这些新增的代码。 IDE 集成 Lombok 还提供了对 IntelliJ IDEA 和 Eclipse 等 IDE 的支持。这意味着在使用这些 IDE 时你可以获得完整的 Lombok 注解支持包括代码补全、导航、重构等特性。 构建工具集成 Lombok 与 Maven 和 Gradle 等构建工具集成确保在构建项目时能够正确处理 Lombok 注解。 无运行时依赖 由于 Lombok 在编译时生成代码因此它不会在运行时添加任何依赖或性能开销。
2.2.idea为什么需要引入lombok插件
Lombok 通过注解来自动生成代码但这些注解发生在编译期。但我们使用ide进行开发的时候在编写代码就已经需要知道注解的语义因此通过插件以便 IDE 能够理解 Lombok 注解并提供相应的代码补全、导航和错误检查功能。 注解处理器集成 Lombok 作为一个 Java 库通过注解处理器在编译时生成额外的代码。IntelliJ IDEA 插件确保了这些注解处理器被正确集成到 IDE 中。 代码补全 插件为 Lombok 提供的注解如 Getter, Setter, ToString 等提供代码补全功能使得开发更加高效。 导航和查找 使用 Lombok 插件IDEA 可以正确导航到 Lombok 生成的方法和构造函数就像它们是手写的一样。 错误检查和代码分析 插件允许 IDEA 对 Lombok 注解进行语义分析提供错误和警告信息帮助开发者避免潜在的问题。 预览生成的代码 在某些情况下插件允许开发者预览 Lombok 注解生成的代码这有助于理解背后的行为。
3、插入式注解处理器
在 Java 中插入式注解处理器Pluggable Annotation Processor允许开发者在编译时期自动处理特定的注解。下面是一个简单的示例演示如何创建和使用自定义注解以及相应的注解处理器。
1.创建自定义注解
首先定义一个注解用来标记需要生成额外代码的类。
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;Retention(RetentionPolicy.SOURCE)
Target(ElementType.TYPE) // 标记在类上
public interface GenerateClass {String value() default DefaultClassName;
}
2.创建注解处理器
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.Processor;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.Element;
import javax.tools.Diagnostic;
import com.google.auto.service.AutoService;
import com.example.annotations.GenerateClass;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.annotation.processing.Filer;
import javax.tools.JavaFileObject;
import java.io.Writer;
import java.util.Set;AutoService(Processor.class)
SupportedAnnotationTypes(com.example.annotations.GenerateClass)
SupportedSourceVersion(javax.lang.model.SourceVersion.RELEASE_8)
public class GenerateClassProcessor extends AbstractProcessor {Overridepublic boolean process(Set? extends TypeElement annotations, RoundEnvironment roundEnv) {for (Element element : roundEnv.getElementsAnnotatedWith(GenerateClass.class)) {GenerateClass generateClass element.getAnnotation(GenerateClass.class);String className generateClass.value();try {Filer filer processingEnv.getFiler();JavaFileObject builderFile filer.createSourceFile(className);try (Writer writer builderFile.openWriter()) {writer.write(public class className {\n);writer.write( public className () {\n);writer.write( System.out.println(\\\New class generated!\\\);\n);writer.write( }\n);writer.write(}\n);}} catch (Exception e) {processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage());}}return true;}
}
3.注册注解处理器
如果你使用了 Google 的 AutoService则注解处理器会自动注册。否则你需要在 META-INF/services 目录下创建一个名为 javax.annotation.processing.Processor 的文件并填入你的处理器的全限定名。
import com.example.annotations.GenerateClass;GenerateClass(value MyGeneratedClass)
public class MyClass {// 这个类会被注解处理器处理并生成 MyGeneratedClass
}
4.编译项目
编译你的项目注解处理器将自动运行并根据 GenerateClass 注解生成新的类文件。
注意事项
注解处理器是在编译时执行的因此它们不会影响运行时性能。确保你的注解处理器类被正确注册以便编译器能够发现并使用它。使用 SupportedAnnotationTypes 和 SupportedSourceVersion 注解来声明你的处理器支持哪些注解和 Java 版本。处理过程中发生的任何异常都需要被捕获并适当处理通常通过 processingEnv.getMessager().printMessage() 打印错误信息。
4、Lombok示例
3.1.javabean注解
注解名称作用Getter用于自动生成字段的get方法。作为类注解则生成该类所有字段的getter方法(static字段不参与)作为字段注解则生成该字段的getter方法。Setter用于自动生成字段的set方法。作为类注解则生成该类所有字段的setter方法(final/static字段不参与)作为字段注解则生成该字段的setter方法。ToString 自动生成 toString() 方法包括类的所有实例字段和final字段不包括static字段。 EqualsAndHashCode自动生成 equals() 和 hashCode() 方法NoArgsConstructor自动生成无参构造函数AllArgsConstructor自动生成包含所有字段的构造函数RequiredArgsConstructo自动生成包含所有非 final 和非静态字段的构造函数并标记为 NonNull 的字段Data组合注解相当于 Getter, Setter, RequiredArgsConstructor, ToString, 和 EqualsAndHashCodeValue类似 Data但生成不可变对象所有字段都是 final 现在对Data注解进行演示
假设一个普通的javabean定义如下
import lombok.Data;Data
public class Person {private int age;private String name;private static String key key;private final String finalField FINALFIELD;
}经过lombok插件的翻译之后变成
import java.util.Objects;public class Person {private int age;private String name;private static String key key;private final String finalField FINALFIELD;public Person() {}public int getAge() {return this.age;}public String getName() {return this.name;}public String getFinalField() {Objects.requireNonNull(this);return FINALFIELD;}public void setAge(final int age) {this.age age;}public void setName(final String name) {this.name name;}public boolean equals(final Object o) {if (o this) {return true;} else if (!(o instanceof Person)) {return false;} else {Person other (Person)o;if (!other.canEqual(this)) {return false;} else if (this.getAge() ! other.getAge()) {return false;} else {Object this$name this.getName();Object other$name other.getName();if (this$name null) {if (other$name ! null) {return false;}} else if (!this$name.equals(other$name)) {return false;}Object this$finalField this.getFinalField();Object other$finalField other.getFinalField();if (this$finalField null) {if (other$finalField ! null) {return false;}} else if (!this$finalField.equals(other$finalField)) {return false;}return true;}}}protected boolean canEqual(final Object other) {return other instanceof Person;}public int hashCode() {int PRIME true;int result 1;result result * 59 this.getAge();Object $name this.getName();result result * 59 ($name null ? 43 : $name.hashCode());Object $finalField this.getFinalField();result result * 59 ($finalField null ? 43 : $finalField.hashCode());return result;}public String toString() {int var10000 this.getAge();return Person(age var10000 , name this.getName() , finalField this.getFinalField() );}
}
3.2.Builder注解
Builder也是一个非常常用的注解为类提供构建器模式支持允许链式调用。对于上面的Person定义使用该注解之后编译器会自动生成一个Builder类。代码大致如下
public class Person$PersonBuilder {private int age;private String name;Person$PersonBuilder() {}public Person$PersonBuilder age(final int age) {this.age age;return this;}public Person$PersonBuilder name(final String name) {this.name name;return this;}public Person build() {return new Person(this.age, this.name);}public String toString() {return Person.PersonBuilder(age this.age , name this.name );}
}
如此客户端便可已链式的方式进行创建实例如下
Person p Person.builder().age(1).name(Tom).build();
3.3.日志类注解
lombok为各种常见的日志框架提供简易注解有如下几个注解。
需要注意的是
log注解只能用于类接口enum或者record等。
注解只提供代码上的引用项目仍然需要引入相关的依赖及配置才能使日志生效。
注解名称作用 Log jdk官方log接口 Log4j log4j日志接口Log4j2log4j2日志接口Slf4jSlf4j日志门面接口
下面以slf4j注解进行演示说明
Slf4j
public class TestLombok {public static void main(String[] args) {log.info(此处是日志);}
}
翻译的代码如下
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class TestLombok {private static final Logger log LoggerFactory.getLogger(TestLombok.class);public TestLombok() {}public static void main(String[] args) {log.info(此处是日志);}
}
3.4.Cleanup注解
在jdk1.7之前对于io资源的使用一般是使用类似的代码需要在io流使用结束后关闭资源。
import java.io.FileInputStream;public class Test {public static void main(String[] args) {FileInputStream fis null;try {fis new FileInputStream(input.txt);} catch (Exception e) {} finally {if (fis ! null) {try {fis.close();} catch (Exception ignore) {}}}}
}jdk1.7引入了try-with-resources语句块可以自动处理单个或多个资源的关闭。类似下面的语法。 public static void main(String[] args) {try ( FileInputStream fis new FileInputStream(input.txt)){// do sth} catch (Exception ignored) {} }
Cleanup做的也是类似的工作。个人觉得该注解比较鸡肋因为jdk已经有官方的实现了。
源代码如下
import lombok.Cleanup;import java.io.FileInputStream;public class Test {public static void main(String[] args) throws Exception {Cleanup var file1 new FileInputStream(input.txt);Cleanup var file2 new FileInputStream(input.txt);Cleanup var file3 new FileInputStream(input.txt);}
}翻译的代码如下
import java.io.FileInputStream;
import java.util.Collections;public class Test {public Test() {}public static void main(String[] args) throws Exception {FileInputStream file1 new FileInputStream(input.txt);try {FileInputStream file2 new FileInputStream(input.txt);try {FileInputStream file3 new FileInputStream(input.txt);if (Collections.singletonList(file3).get(0) ! null) {file3.close();}} finally {if (Collections.singletonList(file2).get(0) ! null) {file2.close();}}} finally {if (Collections.singletonList(file1).get(0) ! null) {file1.close();}}}
}
当然lombok还有其他很多注解但可能使用频率没那么广泛感兴趣的读者可以自行查阅。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/931364.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!