Lombok介绍、使用、神奇操作、以及工作中遇到的一些坑

springboot依赖lombok插件、lombok常用注解 springboot依赖lombok插件、lombok常用注解讲解 阅读详情
AI摘要

本文介绍了Lombok这一Java库,它能通过注解简化Java代码编写,提高开发效率。文中以IntelliJ IDEA为例,说明了其使用方法,分析了工作原理,还分享了一些神奇操作和工作中遇到的坑及解决办法,如equals方法问题、命名冲突等。

介绍:

        在没有lombok之前,我们写一个实体类(或JavaBean或Pojo或叫其他),除了定义基本的属性之外,其他如无参构造方法、有参构造方法、setter/getter、toString、甚至equals、hashCode方法等,以及如果要操作Builder模式的话还需要自己手动编写大篇幅的代码去实现,枯燥,编码量大,还容易出现拼写错误。有了lombok之后,通过在类或属性上添加几个注解,就可以让编辑器在代码编译时帮我们自动生成相应的setter/getter/构造方法等,即提高了开发效率,又提升了代码的可读性(这里我们不和record做比较)。

        一句话总结:lombok是一个java库,通过引入lombok,添加相应的注解,可以简化java代码的编写,提高工作效率。

       

使用:(以IntelliJ IDEA中的使用为例)

环境:java+maven+Intellij IDEA

一、在pom.xml文件中添加lombok依赖:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
    <scope>provided</scope>
</dependency>

maven仓库传送门:查看mvnrepository中的lombok

二、在IDEA中安装lombok插件

在IDE中使用lombok使用还需要安装相应的插件并启用。

打开file-settings在左侧找到plugins,未安装情况下在MarketPlace中搜索lombok进行安装,安装后再次打开可以Installed标签中找到它并启用。

如遇编译时出错,大概率为没有将注解处理器设置为enable状态,打开file-settings中,依次点击:

Build,Execution,Deployment-Compiler-Annotation Processors,勾选Enable annotation processing

使用示例:

不使用lombok的情况:

public class Student implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private Integer age;
    private double score;

    public Student() {
    }

    public Student(String name, Integer age, double score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", score=" + score +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Double.compare(student.score, score) == 0 && Objects.equals(name, student.name) && Objects.equals(age, student.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, score);
    }
}

使用lombok的情况:

@Data
public class Student implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private Integer age;
    private double score;

}

可以看到代码明显简洁了不少,大大提升开发效率。

@Data注解说明:

/**
 * Generates getters for all fields, a useful toString method, and hashCode and equals implementations that check
 * all non-transient fields. Will also generate setters for all non-final fields, as well as a constructor.
 * <p>
 * Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode}.
 * <p>
 * Complete documentation is found at <a href="https://projectlombok.org/features/Data">the project lombok features page for &#64;Data</a>.
 * 
 * @see Getter
 * @see Setter
 * @see RequiredArgsConstructor
 * @see ToString
 * @see EqualsAndHashCode
 * @see lombok.Value
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface Data {
	/**
	 * If you specify a static constructor name, then the generated constructor will be private, and
	 * instead a static factory method is created that other classes can use to create instances.
	 * We suggest the name: "of", like so:
	 * 
	 * <pre>
	 *     public @Data(staticConstructor = "of") class Point { final int x, y; }
	 * </pre>
	 * 
	 * Default: No static constructor, instead the normal constructor is public.
	 * 
	 * @return Name of static 'constructor' method to generate (blank = generate a normal constructor).
	 */
	String staticConstructor() default "";
}

从注释javadoc中可以看出,它会为所有字段生成getter,setter方法,一个有用的toString方法,hashCode方法,equals方法,还有构造方法。

通过添加

@Accessors(chain = true)

可以实现setXXX方法的链式调用

从注解中可以看出,当chain的值设置为true时,setters的返回值会用this替代void。

常用注解:(按字面意思理解即可)

@NoArgsConstrutor:无参构造方法;

@RequiredArgsConstructor:有参构造方法,使用了@NonNull约束的属性;

@AllArgsContructor:全参构造方法;

@Data:setter/getter,tostring,hashcode,equals,requiredArgsConstructor

@Setter,@Getter:setter/getter

@Accessors(chain=true):settter的链式调用

@Builder:将类转变为建造者模式

@EqualsAndHashCode:生成equals和hashCode方法

@Slf4j:生成一个log变量,生private static final修饰,配合日志框架使用;

工作原理分析:

知道lombok是什么了,也知道它怎么用,那它究竟是怎么实现的呢?来分析分析它的工作原理!

lombok的使用是注解,那么它的实现也离不开注解。

jdk1.5在引入注解时,也提供了两种注解解析方式:运行时解析 和 编译时解析 。

运行时解析:@Retention(RetentionPolicy.RUNTIME)

(Retention:保留,RetentionPolicy:保留策略,不同和策略表示注解能保留的时间)

RetentionPolicy.RUNTIME:表示注解将被编译器记录在class文件中,并且在运行时被VM保留,通过反射机制也就可以拿到这个注解了。

java.lang.reflect.AnnotatedElement:一个接口,Class,Field,Method,Constructor,Package等等都实现了这个接口。AnnotatedElement接口中有下面这几个方法获取注解信息:

通过get[Declared]Annotation方法便可获取到对应的注解信息。

编译时解析:

编译时解析有两种机制:APT(Annotation Process Tool)和Pluggable Annotation Processing API,APT由于在jdk7中已被标记为废弃且在jdk8中已删除,所以重点看看Pluggable Annotation Processing API。

Pluggable Annotation Processing API:

Since JDK1.6,从jdk6开始加入,替代apt,解决javac无法使用apt的问题,javac在执行时会调用实现了此API的程序,我们也就可以在这个过程中对编译器做一些增强处理。

.java文件-->javac(解析与填充符号表->注解处理->分析与字节码⽣成->⽣成⼆进制class⽂件)-->.class文件-->vm-->0101...

lombok本质上就是一个实现了JSR 269: Pluggable Annotation Processing API (编译期的注解处理器)的程序,在javac的过程中做如下的处理:

1、通过javac对源码进行分析,生成一棵抽象语法树AST(编程语言源代码的抽象语法结构的树状表示,树的每个节点表示源代码中出现的构造。语法是“抽象的”,因为它不表示源代码的确切文本,而是表示其语法结构);

2、运行过程中调用实现了JSR 269: Pluggable Annotation Processing API (编译期的注解处理器)的lombok程序;

3、lombok程序对AST进行处理,找到由@Data注解所在类对应的语法树,并增加setter,getter等相应的树节点;

4、javac根据修改的AST生成字节码文件(.class)。

 在lombok源码中,则是在HandlerXXX中实现的,如HandlerGetter.handler()

(引入lombok的优点就不用多说了,缺点嘛,感觉就是构造器的重载上支持的不够好)

神奇操作(骚操作):

(主要是几个注解,也是从别的大佬那里看来的,自己再总结归纳下,巩固巩固,源文链接已贴在文章末尾)

onXXX

如:onConstrutor,onMethod,onParam

使用方式:

jdk7:

@RequiredArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))}

jdk8:

@RequiredArgsConstructor(onConstructor_={@AnnotationsGohere})} // note the underscore after {@code onConstructor}

以onConstructor为例,表示在生成构造方法时,在构造方法上会使用的注解

/**
	 * Any annotations listed here are put on the generated constructor.
	 * The syntax for this feature depends on JDK version (nothing we can do about that; it's to work around javac bugs).<br>
	 * up to JDK7:<br>
	 *  {@code @RequiredArgsConstructor(onConstructor=@__({@AnnotationsGoHere}))}<br>
	 * from JDK8:<br>
	 *  {@code @RequiredArgsConstructor(onConstructor_={@AnnotationsGohere})} // note the underscore after {@code onConstructor}.
	 * 
	 * @return List of annotations to apply to the generated constructor.
	 */
	AnyAnnotation[] onConstructor() default {};

 如:在spring相关的注解中(如@Service,@Controller,@Component等),使用@RequiredArgsConstructor(onContructor=@__(@Autowired))的示例如下:

MyService.java

@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MyService {
    private final UserService userService;//想要被lombok注入,这里必须是final修饰
}

生成的 MyService.class

@Service
public class MyService {
  private final UserService userService;
  
  @Autowired
  public MyService(UserService userService) {
    this.userService = userService;
  }
}

@Delegate: 不用写重复代码,直接使用其他类的方法

如:类A有一个方法叫sayHi(String name)和sayBye(String name),如果想要类B也能用sayHi和sayBye方法,只要让类B有拥有一个类A的属性,并在这个属性上加上@Delegate注解,在类B中就可以直接调用类A中的方法(不是通过a.xxx的方法调用,而是直接调用sayHi和sayHello)。

代码示例:

@Cleanup:自动管理输入输出流等各种需要释放的资源,默认调用close方法

 使用方式如:

@Cleanup InputStream is = new FileInputStream("some/file.ext");

看看Cleanup注解的定义:

/**
 * Ensures the variable declaration that you annotate will be cleaned up by calling its close method, regardless
 * of what happens. Implemented by wrapping all statements following the local variable declaration to the
 * end of your scope into a try block that, as a finally action, closes the resource.
 * <p>
 * Complete documentation is found at <a href="https://projectlombok.org/features/Cleanup">the project lombok features page for &#64;Cleanup</a>.
 * <p>
 * Example:
 * <pre>
 * public void copyFile(String in, String out) throws IOException {
 *     &#64;Cleanup FileInputStream inStream = new FileInputStream(in);
 *     &#64;Cleanup FileOutputStream outStream = new FileOutputStream(out);
 *     byte[] b = new byte[65536];
 *     while (true) {
 *         int r = inStream.read(b);
 *         if (r == -1) break;
 *         outStream.write(b, 0, r);
 *     }
 * }
 * </pre>
 * 
 * Will generate:
 * <pre>
 * public void copyFile(String in, String out) throws IOException {
 *     &#64;Cleanup FileInputStream inStream = new FileInputStream(in);
 *     try {
 *         &#64;Cleanup FileOutputStream outStream = new FileOutputStream(out);
 *         try {
 *             byte[] b = new byte[65536];
 *             while (true) {
 *                 int r = inStream.read(b);
 *                 if (r == -1) break;
 *                 outStream.write(b, 0, r);
 *             }
 *         } finally {
 *             if (outStream != null) outStream.close();
 *         }
 *     } finally {
 *         if (inStream != null) inStream.close();
 *     }
 * }
 * </pre>
 */
@Target(ElementType.LOCAL_VARIABLE)
@Retention(RetentionPolicy.SOURCE)
public @interface Cleanup {
	/** @return The name of the method that cleans up the resource. By default, 'close'. The method must not have any parameters. */
	String value() default "close";
}

通过javadoc中的说明,便一目了然,在会try-finally的finally代码块中执行value指定的方法。value的值默认为"close",所以,如果释放资源的方法并非close()则通过value值指定即可。

@Singular:让集合类型的字段更容易维护;

@Builder:让类支持链式构造,注意:只生前当前类的字段和参数,对继承的字段不做处理;

@Singular与@Builder的组合:

@Data
@Builder
class User {
    private String name;
    private int age;
    @Singular
    private List<String> hobbies;
}

User user = User.builder().name("张三")
                    .age(18)
                    .hobbies(Arrays.asList("打篮球", "看电影"))
                    .clearHobbies()//清空hobbies
                    .hobby("听音乐")
                    .build();

@With:创建一个当前对象的副本,更改某些属性的值

With注解定义:

 使用示例:

@With
@AllArgsConstructor
@Data
class Person {
    private String name;
    private int age;
}

Person person = new Person("张三",18);
Person person1 = person.withName("李四");//person对象的副本,name属性改成了李四,age=18
System.out.println(person1.getAge());//18

工作中遇到的一些坑:(请绕行)

一、使用@Data注解生成的equals方法,默认只判断了当前类的属性是否相等,而忽略了父类的属性,从而使两个明显不相等的对象通过equals尽判断为相等。这个坑,在一些去重的场景中很容易踩到,如:set,map中,都是通过equals进行比较进行去除重复的。

示例如:

@Data
class Child {
    private int age;
}

@With
@Builder
@Data
class Person extends Child {
    private String name;
}

Person p1 = new Person("张三");
        p1.setAge(18);
        Person p2 = new Person("张三");
        p2.setAge(20);
        System.out.println(p1.equals(p2));//这里居然输出了true

解决方式:

使用@EnqualsAndHashCode并显示指定canSuper=true,这样就会调用父类的equals

@EqualsAndHashCode(callSuper = true)

不过,这种解决方式,要在所有类中去查找添加,费时费力,容易造成遗漏,可以添加一个lombok.config配置文件,内容写为:

lombok.equalsAndHashCode.callSuper=call

 那么在项目中所有用到@Data注解的类中在生成代码时都会自动加上@EqualsAndHashCode(callSuper=true),从而在全局上解决问题。

二、lombok对于第一个字母小写第二个字母大写的属性,生成的setter/getter方法,与mybatis获取属性的方法容易造成冲突。如sName属性,生成getSName,setSName,但在mybatis中并不能正确的解析到对应的属性名称为sName,原因见下面的源码中的注释。

如:在mybatis(本文为3.5.6)中通过set/get方法获取属性名的源码如下:

/**
 *    Copyright 2009-2019 the original author or authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package org.apache.ibatis.reflection.property;

import java.util.Locale;

import org.apache.ibatis.reflection.ReflectionException;

/**
 * @author Clinton Begin
 */
public final class PropertyNamer {

  private PropertyNamer() {
    // Prevent Instantiation of Static Class
  }

  public static String methodToProperty(String name) {
    if (name.startsWith("is")) {
      name = name.substring(2);
    } else if (name.startsWith("get") || name.startsWith("set")) {
      name = name.substring(3);
    } else {
      throw new ReflectionException("Error parsing property name '" + name + "'.  Didn't start with 'is', 'get' or 'set'.");
    }
    //这里是重点
    //如果属性长度为1,如private int x; public int getX(),name属性就是x
    //如果属性长度大于1,此时还会判断第二个字母是否为大写,如果不是大写的情况下,才会对第一个字母转换为小写处理,如果我们的属性叫:sName,那会getSName就不会被转把sName这个正确的属性
    if (name.length() == 1 || (name.length() > 1 && !Character.isUpperCase(name.charAt(1)))) {
      name = name.substring(0, 1).toLowerCase(Locale.ENGLISH) + name.substring(1);
    }

    return name;
  }

  public static boolean isProperty(String name) {
    return isGetter(name) || isSetter(name);
  }

  public static boolean isGetter(String name) {
    return (name.startsWith("get") && name.length() > 3) || (name.startsWith("is") && name.length() > 2);
  }

  public static boolean isSetter(String name) {
    return name.startsWith("set") && name.length() > 3;
  }

}

踩坑的重点见代码中的中文注释部分,规避方式也就是尽量避免这种命名方式吧!!!

三、@Accessors(chain=true)与excel导出工具(如easyexcel)在使用中遇到的坑

首先,说下@Accessors(chain=true)注解,当实体类被此注解标记时,我们在调用这个实体类的setXXX方法就可以使用链式调用了,因为它setXXX当chaine=true返回的是this而非void。

在easyexcel中,是通过cglib做为反射工具包的。

cglib中则使用rt.jar中的Introspector这个类的方法来获取get和set方法进一步获取属性的,Introspector类中的实现,在判断setXXX方法加了一个判断返回值是否为Void的条件,此时,返回this的setXXX方法将会被过滤。。。

解雇方案:不用@Accessors(chain=true)...

四、@Builder默认值的坑

在lombok1.18.4版本之前,字段属性上的默认值,通过build构建出来的对象并没有赋值。

如:

@Data
@Builder
@Accessors(chain = true)
public class Student implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

    private String name = "张三";//默认值设为张三
    private Integer age;
    private double score;

    public static void main(String[] args) {
        Student student = Student.builder().build();
        System.out.println(student);
    }

}

输出:

这与预期的不符啊,name居然不是“张三”

解决方案1:在name属性上添加@Builder.Default注解

@Builder.Default
    private String name = "张三";//默认值设为张三

输出:

解决方案2:在@Builder注解中增加toBuilder=true

@Data
@Builder(toBuilder = true)
@Accessors(chain = true)
public class Student implements java.io.Serializable {
    private static final long serialVersionUID = 1L;

    private String name = "张三";//默认值设为张三
    private Integer age;
    private double score;

    public static void main(String[] args) {
        Student student = Student.builder().build();
        System.out.println(student);
    }

}

输出:

问题并没有解决!!!

调整main方法:

        Student student = new Student();
        System.out.println(student);

        Student student1 = new Student().toBuilder().build();
        System.out.println(student1);

输出:

这次是正常的,说明我们必须先进行实例化(new Student())才能构造(build()),否则默认值还是不生效!!!

五、当@Data和@Builder结合使用的时候,要注意,总会有些方法不会自动生成,这个就留着慢慢踩吧,发现要用的时候没有生成再去单独添加相应的注解:(

本文中引参及参考过的一些链接:

lombok官网

盘点Lombok的几个骚操作

Java 开发中的 Lombok 是什么? 我看了后,发现有些学生的idea版本是2020.3版本,与之前大多数人使用的2020.1版本不同,造成Lombok插件的安装配置也有所差异。然后我仔细看了下他的代码,发现Mybatis的使用确实没错,但发现代码中Lombok插件的@Builder注解使用有误。Lombok插件的使用比较简单,就是在实体类中,只需要写入相应的属性,然后在类上面添加相应的注解即可。如果你还有什么别的疑问,可以在评论区留言哦。我起床拿手机,还差点摔倒闪了我的老腰,我老婆看我这么着急还以为我有了小三儿 ,打得我满脸血呼刺啦的。 阅读详情

相关推荐

Lombok插件的安装和使用详解

我们知道,Lombok插件是目前Java中使用频率非常高的一款插件,可以在编译阶段自动生成实体类的常用方法。// 没有使用Lombok插件的实体类,需要手动写getter和setter,以及构造方法等return id;return age;// 使用了Lombok插件的实体类@Data // 此注解自动生成getter和setter,toString,equals和hashCode等方法@NoArgsConstructor // 此注解生成无参构造函数。

关注我!带你一路 "狂飙" 到底! 4981

Lombok-全面详解(学习总结---从入门到深化)

以前的Java项目中,充斥着太多不友好的代码:POJO的 getter/setter/toString/构造方法;打印日志;I/O流的关闭操作等 等,这些代码既没有技术含量,又影响着代码的美观,Lombok应 运而生。LomBok可以通过,帮助开发人员消除JAVA中尤其是POJO类中 的冗长代码。1、使用LomBok之前2、使用LomBok之后。

1万+

Mac 环境配置jdk、Maven

3、终端打开配置jdk时候建好的脚本文件: open -e .bash_profile。4、查看maven是否安装成功和系统能不能识别maven/mvn命令:⬇️。输入⬇️并保存: 其中第一行JAVA_HOME替换为自己下的jdk路径。,安装编译好的二进制版本,具体安装zip还是tar.gz我看的。5、查看jdk是否安装成功和系统能不能识别java命令:⬇️。至此,我的Mac系统的环境配置jdk、Maven完成!然后就发现我的maven命令还是没作用,不识别,下载后直接安装即可,很快,点几下就OK了。

weixin_42416791的博客 4387

Lombok超详解

以前的Java项目中,充斥着太多不友好的代码:POJO的getter/setter/toString/构造方法;打印日志;I/O流的关闭操作等等,这些代码既没有技术含量,又影响着代码的美观,Lombok应运而生。LomBok可以通过注解,帮助开发人员消除JAVA中尤其是POJO类中的冗长代码。使用LomBok之前使用LomBok之后。

qq_53317005的博客 1万+

手把手教你用STM32F429+FreeRTOS搭建开源SIP电话(附代码与避坑指南)

本文详细介绍了如何使用STM32F429和FreeRTOS搭建开源SIP电话系统,涵盖硬件选型、FreeRTOS任务划分、PJSIP协议栈移植、音频系统优化及安全实践。通过实战案例和代码示例,帮助开发者快速实现嵌入式VoIP通信,特别适合物联网和音视频通信领域的应用开发。

weixin_33582311的博客 354

当迁移学习遇见室内定位:基于UJIIndoorLoc的跨场景适配实践

本文探讨了迁移学习在跨建筑室内定位中的应用,重点解析了UJIIndoorLoc数据集的特性及其在解决设备差异和环境变化中的关键作用。通过特征工程、迁移学习策略和小样本微调技术,显著提升了定位模型的跨场景适配能力,为实际部署提供了有效解决方案。

weixin_29038155的博客 394

Lombok 介绍+使用

Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。 Lombok能通过注解的方式,在编译时自...

不坠青云 3万+

LiveReload:释放你的F5,实时预览HTML效果

一、liveReload插件开发背景Web前端开发人员在写页面时,如果修改了HTML or CSS,要想看效果通常的做法就是保存代码就得 Alt+Tab,切换到浏览器(当然,我知道很多开发人员是双屏操作不一定需要切换到浏览器),但是一定要F5刷新才能看自己刚写的代码有没有效果,没有效果就再切换到编辑器下修改,然后再切换到浏览器F5刷新看效果,还没有效果,就再继续修改,如此反复。时间久了,前端自动化...

Char_n的博客 2506

Lombok介绍、使用方法和总结

1 Lombok背景介绍 官方介绍如下: Project Lombok makes java a spicier language by adding ‘handlers’ that know how to build and compile simple, boilerplate-free, not-quite-java code. 大致意思是Lombok通过增加一些“处理程序”,可以让java...

u013131716的博客 3297

QSPI Flash的原理与QSPI时序的Verilog实现

本节主要是讨论QSPI(Quad SPI,四线SPI总线)的相关内容。我的开发板上有一片型号是W25Q128BV的Quad SPI Flash存储器,本文将以它为例子来说明QSPI操作的一些内容。

Go Forward Forever! 4164

【异常】OpenClaw网关仪表盘 pairing required 报错排查与解决方案

在OpenClaw网关仪表盘页面,完成WebSocket URL、网关令牌等必填项配置后,点击「连接」按钮尝试建立网关连接时,页面下方出现红色报错提示框,核心报错内容为,无法完成网关连接建立,且该报错在令牌配置正确、网络链路通畅的场景下仍会触发。该报错常见于非本地回环地址的访问场景,包括局域网远程访问、公网域名/IP访问、云服务器部署的网关远程管理等场景,本地127.0.0.1回环地址访问通常可正常连接。

奶爸的编程之路,也就一周冷个三天 1077

Lombok介绍、使用方法和安装

优点: 1. 能通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,提高了一定的开发效率 2. 让代码变得简洁,不用过多的去关注相应的方法 3. 属性做修改时,也简化了维护为这些属性所生成的getter/setter方法等 缺点: 1. 不支持多种参数构造器的重载 2. 虽然省去了手动创建getter/setter方法的麻烦,但大大降低了源代码的可读性和完整性,降低了阅读源代码的舒适度

棉花糖老丫 1012

久坐不慌,健康护航 —— 智能震动提醒坐垫的设计与实现

硬件核心:选用 ESP32 为主控,HX711 + 应变片实现精准压力检测,8050 三极管驱动震动马达,锂电池 + TP4056 满足便携供电需求;软件逻辑:核心是 “压力阈值判断 + 时间计时”,达到久坐阈值后触发震动提醒,流程图清晰体现了循环检测、状态重置的核心逻辑;代码特性:代码注释完善,阈值可灵活调整,支持串口调试,新手可直接编译烧录并根据实际场景校准。

weixin_42300449的博客 398

Java神奇工具——Lombok[最全]

最近刚接触,结果官网访问速度很慢,网上博客又没有介绍全,打算自己做个详细的,以防后面复习使用。 目录   Lombok 如何用Lombok——两种方法 有哪些注解可以使用呢[1.16.18版本一共18个注解,有一个注解不推荐使用] @AllArgsConstructor / @NoArgsConstructor / @RequiredArgsConstructor @Builde...

IPOmonkey的博客 6433

【推荐100个unity插件】性能极高的逼真爆炸、火焰和烟雾效果——UNI VFX

这是一篇关于Unity中高性能GPU粒子特效插件UNI VFX的使用指南。文章介绍了该插件提供逼真的爆炸、火焰和烟雾效果,支持URP和HDRP渲染管线。主要内容包括:插件安装方法(需预先安装Visual Effect Graph和Shader Graph包)、事件系统使用方法(如create/loop/stop等事件控制)、特效分类(自动结束型和持续型特效)、检视面板配置技巧以及性能优化建议(特别提醒灯光特效对性能的影响较大)。文末还推荐了多个Unity开发相关的专栏内容。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 1487

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

科普文:Lombok使用及工作原理详解

举例来说,现在有一个实现了Pluggable Annotation Processing API的程序A,那么使用javac编译时的具体流程如下: 1. javac编译器对源码进行分析,生成一个抽象的语法树(AST) 2. javac编译器运行A程序 3. A程序完成逻辑,一般是修改此语法树 4. javac使用修改后的语法树生成可执行的字节码文件 Lomok便是通过Pluggable Annotation Processing API来实现代码生成的。

为无为,事无事,味无味。 2908

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

lombok原理_Lombok介绍、使用方法、工作原理和总结

1 Lombok背景介绍官方介绍如下:Project Lombok makes java a spicier language by adding 'handlers' that know how to build and compile simple, boilerplate-free, not-quite-java code.大致意思是Lombok通过增加一些“处理程序”,可以让java变得简...

weixin_39636987的博客 125

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

lombok介绍、使用方法、总结

1 Lombok背景介绍 官方介绍如下: Project Lombok makes java a spicier language by adding 'handlers' that know how to build and compile simple, boilerplate-free, not-quite-java code. 大致意思是Lombok通过增加一些“处理程序”,可以让...

黎小小的博客 305

Lombok/slf4j介绍及使用方法

Lombok介绍及使用方法 lombok简介 lombok是暑假来到公司实习的时候发现的一个非常好用的小工具,刚见到的时候就感觉非常惊艳,有一种相见恨晚的感觉,用了一段时间之后感觉的确挺不错,所以特此来推荐一下。 lombok的官方地址:https://projectlombok.org/ lombok的Github地址:https://github.com/rzwitserloot/lombok 那么lombok到底是个什么呢,lombok是一个可以通过简单的注解的形式来帮助我们简化消除一些必须

qq_40435659的博客 1万+

Lombok插件介绍、使用方法、工作原理和总结 侵立删

转自:https://www.cnblogs.com/heyonggang/p/8638374.html 1 Lombok背景介绍 官方介绍如下: Project Lombok makes java a spicier language by adding 'handlers' that know how to build and compile simple, boilerplate-f...

心神沫沫的收藏 1136

Lombok介绍及使用方法

Lombok介绍及使用方法 lombok简介 lombok是暑假来到公司实习的时候发现的一个非常好用的小工具,刚见到的时候就感觉非常惊艳,有一种相见恨晚的感觉,用了一段时间之后感觉的确挺不错,所以特此来推荐一下。 lombok的官方地址:https://projectlombok.org/ lombok的Github地址:https://github.com/rzwitserloot/lombok 那么lombok到底是个什么呢,lombok是一个可以通过简单的注解的形式来帮助我们简化消除一些必须

月亮的技术博客 612
上一篇: 关于java中的Date类以及用java.time包下的替代Date的记录
下一篇: 在java项目中使用Ip2Region离线开源API实现IP归属地转换
Jack_abu
博客等级 码龄10年 633粉丝 78原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jack_abu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值