Lombok —— @ToString

本文详细介绍了Lombok的@ToString注解的使用,包括exclude、@ToString.Exclude、includeFieldNames、onlyExplicitlyIncluded、of、@ToString.Include、doNotUseGetters和callSuper等属性的用法,展示了如何自定义toString方法的输出内容和顺序,以及如何处理父类信息。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

Lombok —— @ToString

@ToString 这个注解只能加在类上,不支持加在方法上

package cn.edu.hziee.pojo;

import lombok.ToString;

@ToString
public class User {
    private String userName;
    private String password;
    private Integer age;
    private String phone;
    private String[] interest;
    private Boolean isMale;
}
image-20220412134311680

查看 .class 文件

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package cn.edu.hziee.pojo;

import java.util.Arrays;

public class User {
    private String userName;
    private String password;
    private Integer age;
    private String phone;
    private String[] interest;
    private Boolean isMale;

    public User() {
    }

    public String toString() {
        return "User(userName=" + this.userName + ", password=" + this.password + ", age=" + this.age + ", phone=" + this.phone + ", interest=" + Arrays.deepToString(this.interest) + ", isMale=" + this.isMale + ")";
    }
}

未添加 @ToString 时输出的结果

User = cn.edu.hziee.pojo.User@511baa65

添加 @ToString 后输出的结果

User = User(userName=null, password=null, age=null, phone=null, interest=null, isMale=null)

1、exclude()、@ToString.Exclude

1.1、exclude()

排除某个变量在 ToString 方法中的输出

在 @ToString 方法中添加 exclude() 属性

查看 Lombok 源码发现 exclude 是一个 String 类型的数组变量

String[] exclude() default {};

示例

package cn.edu.hziee.pojo;

import lombok.AllArgsConstructor;
import lombok.ToString;

@ToString(exclude = {"phone", "password"})
@AllArgsConstructor
public class User {
    private String userName;
    private String password;
    private Integer age;
    private String phone;
    private String[] interest;
    private Boolean isMale;

    public static void main(String[] args) {
        System.out.println("User = " + new User("张三", "123456", 13, "123456789123", new String[]{"吃饭", "编程"}, true));
    }
}

运行结果

User = User(userName=张三, age=13, interest=[吃饭, 编程], isMale=true)

但是查看注释发现,该方法将要被标记过时。推荐使用 @ToString.Exclude 注解

Any fields listed here will not be printed in the generated toString implementation. Mutually exclusive with of().
Will soon be marked @Deprecated; use the @ToString.Exclude annotation instead.
Returns:
A list of fields to exclude

此处列出的任何字段都不会在生成的 toString 实现中打印。与 of() 互斥。
很快就会被标记为@Deprecated;请改用 @ToString.Exclude 批注。
返回:
要排除的字段列表

1.2、@ToString.Exclude

源码声明

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.SOURCE)
public @interface Exclude {}

官方注释:

If present, do not include this field in the generated toString.

如果存在,请勿在生成的 toString 中包含此字段

package cn.edu.hziee.pojo;

import lombok.AllArgsConstructor;
import lombok.ToString;

@ToString
@AllArgsConstructor
public class User {
    private String userName;
    @ToString.Exclude
    private String password;
    private Integer age;
    @ToString.Exclude
    private String phone;
    private String[] interest;
    private Boolean isMale;

    public static void main(String[] args) {
        System.out.println("User = " + new User("张三", "123456", 13, "123456789123", new String[]{"吃饭", "编程"}, true));
    }
}

运行结果

User = User(userName=张三, age=13, interest=[吃饭, 编程], isMale=true)

2、includeFieldNames()

源码该方法的声明:

boolean includeFieldNames() default true;

官方注释

Include the name of each field when printing it. default: true
Returns:
Whether or not to include the names of fields in the string produced by the generated toString().

打印时包括每个字段的名称。默认值:真
返回:
是否在生成的 toString() 生成的字符串中包含字段名称。

实现:

package cn.edu.hziee.pojo;

import lombok.AllArgsConstructor;
import lombok.ToString;

@ToString(includeFieldNames = false)
@AllArgsConstructor
public class User {
    private String userName;
    private String password;
    private Integer age;
    private String phone;
    private String[] interest;
    private Boolean isMale;

    public static void main(String[] args) {
        System.out.println("User = " + new User("张三", "123456", 13, "123456789123", new String[]{"吃饭", "编程"}, true));
    }
}

运行结果:

User = User(张三, 123456, 13, 123456789123, [吃饭, 编程], true)

未添加 includeFieldNames 属性时的运行结果

User = User(userName=张三, password=123456, age=13, phone=123456789123, interest=[吃饭, 编程], isMale=true)

3、onlyExplicitlyIncluded ()、of() 与 @ToString.Include

源码中的方法声明

boolean onlyExplicitlyIncluded() default false;

String[] of() default {};

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Include {
    int rank() default 0;
    String name() default "";
}

基本使用方法

package cn.edu.hziee.pojo;

import lombok.AllArgsConstructor;
import lombok.ToString;

@ToString(onlyExplicitlyIncluded = true)
@AllArgsConstructor
public class User {
    @ToString.Include
    private String userName;
    @ToString.Include
    private String password;
    private Integer age;
    private String phone;
    private String[] interest;
    private Boolean isMale;

    public static void main(String[] args) {
        System.out.println("User = " + new User("张三", "123456", 13, "123456789123", new String[]{"吃饭", "编程"}, true));
    }
}

运行结果:

User = User(userName=张三, password=123456)
3.1、of()

of() 的官方注释

If present, explicitly lists the fields that are to be printed. Normally, all non-static fields are printed.
Mutually exclusive with exclude().
Will soon be marked @Deprecated; use the @ToString.Include annotation together with @ToString(onlyExplicitlyIncluded = true).
Returns:
A list of fields to use (default: all of them)

如果存在,则明确列出要打印的字段。通常,会打印所有非静态字段。
与 exclude() 互斥。
很快就会被标记为@Deprecated;将@ToString.Include 注释与@ToString(onlyExplicitlyIncluded = true) 一起使用。
返回:
要使用的字段列表(默认值:全部)

of() 方法将被标记过时 于是推荐使用官方推荐的 @ToString.Include 注解

3.2、@ToString.Include
rank()

rank() 方法的官方注释

Higher ranks are printed first. Members of the same rank are printed in the order they appear in the source file.
Returns:
ordering within the generating toString(); higher numbers are printed first.

首先打印更高的等级。相同等级的成员按照它们在源文件中出现的顺序打印。
返回:
在生成 toString() 中排序;首先打印较大的数字

示例:

package cn.edu.hziee.pojo;

import lombok.AllArgsConstructor;
import lombok.ToString;

@ToString(onlyExplicitlyIncluded = true)
@AllArgsConstructor
public class User {
    @ToString.Include(rank = 1)
    private String userName;
    @ToString.Include(rank = 2)
    private String password;
    private Integer age;
    private String phone;
    private String[] interest;
    private Boolean isMale;

    public static void main(String[] args) {
        System.out.println("User = " + new User("张三", "123456", 13, "123456789123", new String[]{"吃饭", "编程"}, true));
    }
}

运行结果:

  • 使用后

    User = User(password=123456, userName=张三)
    
  • 使用前

    User = User(userName=张三, password=123456)
    
name()

name() 方法的官方注释

Defaults to the field / method name of the annotated member. If the name equals the name of a default-included field, this member takes its place.
Returns:
The name to show in the generated toString(). Also, if this annotation is on a method and the name matches an existing field, it replaces that field.

默认为注释成员的字段/方法名称。如果名称等于默认包含字段的名称,则该成员将代替它。
返回:
要在生成的 toString() 中显示的名称。此外,如果此注释在方法上并且名称与现有字段匹配,它将替换该字段。

示例:

package cn.edu.hziee.pojo;

import lombok.AllArgsConstructor;
import lombok.ToString;

@ToString(onlyExplicitlyIncluded = true)
@AllArgsConstructor
public class User {
    @ToString.Include(name = "name")
    private String userName;
    @ToString.Include(name = "pwd")
    private String password;
    private Integer age;
    private String phone;
    private String[] interest;
    private Boolean isMale;

    public static void main(String[] args) {
        System.out.println("User = " + new User("张三", "123456", 13, "123456789123", new String[]{"吃饭", "编程"}, true));
    }
}

运行结果:

  • 使用后

    User = User(name=张三, pwd=123456)
    
  • 使用前

    User = User(userName=张三, password=123456)
    

4、doNotUseGetters()

源码方法声明:

boolean doNotUseGetters() default false;

官方注释:

Normally, if getters are available, those are called. To suppress this and let the generated code use the fields directly, set this to true. default: false
Returns:
If true, always use direct field access instead of calling the getter method.

通常,如果 getter 可用,就会调用它们。要抑制这种情况并让生成的代码直接使用字段,请将其设置为 true。默认值:假
返回:
如果为 true,则始终使用直接字段访问而不是调用 getter 方法。

示例:

  • 为使用前

    package cn.edu.hziee.pojo;
    
    import lombok.Getter;
    import lombok.ToString;
    
    @ToString
    @Getter
    public class User {
        private String userName;
        private String password;
        private Integer age;
        private String phone;
        private String[] interest;
        private Boolean isMale;
    }
    
    

    编译生成的 .class 文件中的 toString 方法

    public String toString() {
        return "User(userName=" + this.getUserName() + ", password=" + this.getPassword() + ", age=" + this.getAge() + ", phone=" + this.getPhone() + ", interest=" + Arrays.deepToString(this.getInterest()) + ", isMale=" + this.getIsMale() + ")";
    }
    

    从反编译 .class 生成的 .java 文件中可以看出 toString() 方法调用的是 此类的 get() 方法

  • 使用后

    package cn.edu.hziee.pojo;
    
    import lombok.Getter;
    import lombok.ToString;
    
    @ToString(doNotUseGetters = true)
    @Getter
    public class User {
        private String userName;
        private String password;
        private Integer age;
        private String phone;
        private String[] interest;
        private Boolean isMale;
    }
    

    反编译 .class 后的 .java 文件中的 toString 方法

    public String toString() {
        return "User(userName=" + this.userName + ", password=" + this.password + ", age=" + this.age + ", phone=" + this.phone + ", interest=" + Arrays.deepToString(this.interest) + ", isMale=" + this.isMale + ")";
    }
    

    从反编译 .class 生成的 .java 文件中可以看出 toString() 方法不在调用的此类的 get() 方法

5、callSuper()

源码方法声明:

boolean callSuper() default false;

官方注释:

Include the result of the superclass’s implementation of toString in the output. default: false
Returns:
Whether to call the superclass’s toString implementation as part of the generated toString algorithm.

在输出中包含父类实现 toString 的结果。默认值:假
回报:
是否调用父类的 toString 实现作为生成的 toString 算法的一部分

示例:

  1. Base (父类)

    package cn.edu.hziee.pojo;
    
    import lombok.NoArgsConstructor;
    import lombok.Setter;
    import lombok.ToString;
    
    @Setter
    @ToString
    @NoArgsConstructor
    public class Base {
        private Integer id;
    }
    
  2. User(继承 Base类)

    package cn.edu.hziee.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.ToString;
    
    @ToString(callSuper = true)
    @AllArgsConstructor
    public class User extends Base{
        private String userName;
        private String password;
        private Integer age;
        private String phone;
        private String[] interest;
        private Boolean isMale;
    
    
        public static void main(String[] args) {
            User user = new User("张三", "123456", 13, "123456789123", new String[]{"吃饭", "编程"}, true);
            user.setId(1);
            System.out.println("User = " + user);
        }
    }
    
  3. 运行结果

    • 使用

      User = User(super=Base(id=1), userName=张三, password=123456, age=13, phone=123456789123, interest=[吃饭, 编程], isMale=true)
      
    • 不使用

      User = User(userName=张三, password=123456, age=13, phone=123456789123, interest=[吃饭, 编程], isMale=true)
      
  4. 反编译 .class 后的 .java 文件中的 toString 方法

    public String toString() {
        return "User(super=" + super.toString() + ", userName=" + this.userName + ", password=" + this.password + ", age=" + this.age + ", phone=" + this.phone + ", interest=" + Arrays.deepToString(this.interest) + ", isMale=" + this.isMale + ")";
    }
    

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bit-apk-code

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

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

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

打赏作者

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

抵扣说明:

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

余额充值