有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

如何在Java中创建哑“结构”的静态最终实例?

我有一个不强制任何不变量的结构(即它的存在是为了承载其他类的数据),因此它的字段是公共的,并且没有(声明的)构造函数:

public class Observation {
    public short truncatedSeed;
    public final int[] levels = { 0, 0, 0 };
    public final int[] stride1 = { -1, -1, -1 };
    public final int[] stride2 = { -1, -1, -1 };
    public int power = -2;
    public long now = -1; // Not used in equals()/hashCode()
    @Nullable public Item item;
}

如果我想创建这个static final实例,我该怎么做?新的Java是否最终引入了处理这种情况的好语法?我能想到的最好的办法是:

public static final EMPTY = new Observation() {
    {
        truncatedSeed = (short) 0xDEAD;
        item = Item.EMPTY;
    }
};

。。。这确实有效,但创建了一个匿名子类,它似乎。。。讨厌

编辑:因为Java的final很浅,所以这里的所有成员都是不可变的。鉴于此,最直接的方法可能是接受这一事实:

public static EMPTY = new Observation();
static {
    truncatedSeed = (short) 0xDEAD;
    item = Item.EMPTY;
}

共 (2) 个答案

  1. # 1 楼答案

    Have newer Javas finally introduced good syntax for handling this case?

    对。两次,甚至两次

    但是,根据定义,记录是immutable。每个字段都是隐式的final。它们也不支持某些字段具有默认值,并且不支持构建器Arriving in Java 16

    A constructor would just be a bunch of extra boilerplate for this one thing.

    是的。龙目山就是这样做的。得到了大量的样板文件。如果您希望,它们会得到一个生成器,并且可以为各个字段设置默认值@Value默认为不变性,但如果需要,可以“取消”字段,还可以创建类型层次结构;所有的事情都是记录不能做的。此外,lombok从java6开始工作,记录是预览功能,至少在Java16(2021年3月)之前,如果不启用它们,就无法充分使用它们

    The syntax is would prefer would be something like: (from CPP):

    struct A { int x; int y; int z; };
    A b{.x = 1, .z = 2}; // ok, b.y initialized to 0
    

    这实际上是“命名参数”,而java没有。但它有方法,也有名称。在爪哇语中,使用龙目语:

    @Builder @Value class A { int x, y, z; }
    A a = A.builder().x(1).z(2).build(); // ok, y initialized to 0.
    
  2. # 2 楼答案

    您可以使用要初始化的这两个参数创建一个构造函数。(毕竟,Java总是需要一个构造函数来创建新对象。)

    import lombok.*;
    
    @NoArgsConstructor
    @RequiredArgsConstructor
    public class Observation {
      ...
    }
    
    public static final EMPTY = new Observation(0xDEAD, Item.EMPTY);