【问题标题】:Initialize list if list is null with lombok getter?如果列表为空,则使用lombok getter初始化列表?
【发布时间】:2016-11-26 02:24:37
【问题描述】:

我目前正在替换所有标准 POJO,以便将 Lombok 用于所有样板代码。我发现自己为列表保留了 getter,因为如果列表尚未初始化,我想返回一个空列表。也就是说,我不希望 getter 返回 null。如果有一些我不知道的龙目岛魔法可以帮助我避免这样做?

生成代码示例

private List<Object> list;
public Object getList(){ return list; }

我想要什么:

private List<Object> list;
public Object getList(){
    if (list == null) {
        return new ArrayList();
    }
    return list;
}

【问题讨论】:

  • 为什么不直接初始化列表呢?
  • "如果列表没有被初始化" 我认为这是一个错误。如果由于某种原因您想要/需要延迟初始化,您可以查看文档 - 不可能错过 @Getter(lazy=true)。顺便说一句,所需的代码与最初初始化列表的代码相同。
  • @JFMeier 初始化变量不会阻止使用 x.setList(null) 发生。所以 getList() 不能保证不为空。

标签: java java-8 lombok


【解决方案1】:

一个老问题,但是这个插件可以满足你的需求:

https://github.com/dmak/jaxb-xew-plugin

使用此插件生成的 getter 为:

public List<BaseVariableType> getVariables() {
    if (variables == null) {
        variables = new ArrayList<BaseVariableType>();
    }
    return variables;
}

【讨论】:

    【解决方案2】:

    如果提供具有相同名称和参数数量的 getter 方法,最新版本的 lombok 不会生成 getter 方法。

    对于旧版本的 lombok,您可以通过在字段上使用 AccessLevel.NONE 来使用任何您喜欢的内容覆盖 getter。

    请注意,仅初始化该字段并不能保护您免受客户端调用带有 null 的构造函数或调用带有 null 的 setter 的影响(仍然可能没问题,具体取决于您想要的内容)。

    例如

    // only necessary for older versions of lombok
    @Getter(AccessLevel.NONE)
    private Map<String, String> params;
    
    public Map<String, String> getParams() {
        return (params == null) ? new HashMap<>() : params;
    }
    

    【讨论】:

    • 读者应该知道Collections.emptyMap()返回一个不可变映射(通过此调用获取映射时无法添加条目)。
    • 我换成了 new HashMap()
    • 请注意返回 new HashMap() 可能会导致数据丢失。考虑以下代码:``` p = yourObject.getParams(); p.put("k","v"); actualParams = yourObject.getParams(); assert actualParams.size() == 1 //在这里会失败,因为 params 字段保持未修改 ```
    • 现在,您不需要甚至需要用@Getter(AccessLevel.NONE) 标记该字段。如果您要定义自己的 getter 方法,Lombok 不会创建一个:“如果任何方法已经存在且具有相同的名称(不区分大小写)和相同的参数计数,则不会生成任何方法。” (见documentation)。
    • @Jacob:谢谢,我改变了。如果您愿意,请随时进一步更新我的答案。
    【解决方案3】:

    我和这个问题有同样的问题。虽然,上述答案在某些方面很有用,但确切的解决方案是使用 Lombok API 的@Builder and @Singular 注释,如下面给定的代码。

    这对我来说效果很好。

    @Builder
    class MyClass{
        @Singular
        private List<Type> myList;
    }
    

    这将使用非空 List 对象初始化 myList。虽然,这个问题是一个老问题。但是,仍然发布此答案以帮助像我这样将来会参考此问题的人。

    【讨论】:

    • 酷!但这不是 only 与构建器一起工作吗?文档说这个列表是不可变的。
    • 是的,但是 POJO 中的集合仍然为空。
    【解决方案4】:

    您可以通过声明和初始化字段来实现这一点。初始化将在封闭对象初始化时完成。

    private List<Object> list = new ArrayList();
    

    Lomboks @Getter 注解提供了一个属性lazy,它允许延迟初始化。

     @Getter(lazy=true) private final double[] cached = expensiveInitMethod();
    

    Documentation

    【讨论】:

    • “Lombok 不支持在读取时初始化” 实际上它支持。
    • @zeroflagL 谢谢,我从来没有使用过这个,因为使用 '@Data' 是不可能的,但是 java 的方式是。
    【解决方案5】:

    也就是说,我不希望 getter 返回 null。如果有一些我不知道的龙目岛魔法可以帮助我避免这样做?

    你不需要任何魔法来发生。只需初始化list

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-15
      • 1970-01-01
      • 1970-01-01
      • 2013-10-07
      • 2011-06-05
      • 2015-08-04
      • 2012-12-31
      • 2017-03-19
      相关资源
      最近更新 更多