java - 允许最终字段采用默认值

标签 java final

我正在为二进制文件格式编写一个解析器。我创建了类来表示我正在阅读的反序列化结构,我想在其中使用 final 变量来保存提取的数据。

class MyObject {
    final int my_x;
    final int my_y;
    final int my_z;
}

我遇到的问题是某些字段的存在取决于设置的某些标志。例如:

MyObject(InputStream is) {
    my_x = in.read();
    if (my_x == 1) {
        my_y = in.read();
        if (my_y == 1) {
            my_z = in.read();
        }
    }
}

但是,这给了我一个错误,因为 my_ymy_z 可能未初始化。这些条件可以是 5-6 级深,并且我不想跟踪分支树的每一级可能无法读取哪些字段。另一个复杂之处是,根据某些标志,我可能希望使用与顶级结构相同的模式来处理某些子对象。

class MyObject {
    final int my_x;
    final SubObject my_subobject;

    MyObject(InputStream is) {
        my_x = is.read();
        if (my_x == 1)
            my_subobject = new SubObject(is);
    }

    class SubObject {
        final int sub_x;
        final int sub_y;

        SubObject(InputStream is) {
            sub_x = is.read();
            if (sub_x == 1)
                sub_y = is.read();
        }
    }
}

有什么方法可以使我的字段成为最终字段,而无需扭曲代码来处理每种可能的标志组合?

最佳答案

使用局部变量并分配给构造函数末尾的final字段。

public MyObject(InputStream is) {
    int x = default_x_value;
    int y = default_y_value;
    int z = default_z_value;
    x = in.read();
    if (x == 1) {
        y = in.read();
        if (y == 1) {
            z = in.read();
        }
    }
    my_x = x;
    my_y = y;
    my_z = z;
}

或者(正如 Jon Skeet 在他的评论中建议的那样),使用静态工厂方法来计算无默认构造函数的适当值:

public static MyObject makeMyObject(InputStream is) {
    int x = default_x_value;
    int y = default_y_value;
    int z = default_z_value;
    x = in.read();
    if (x == 1) {
        y = in.read();
        if (y == 1) {
            z = in.read();
        }
    }
    return new MyObject(x, y, z);
}

第三种方法是定义一个初始化对象类:

public class MyObject {
    private static class MyObjectInitializer {
        int x = default_x_value;
        int y = default_y_value;
        int z = default_z_value;
        MyObjectInitializer(InputStream is) {
            x = in.read();
            if (x == 1) {
                y = in.read();
                if (y == 1) {
                    z = in.read();
                }
            }
        }
    }
    public MyObject(InputStream is) {
        this(new MyObjectInitializer(is));
    }
    private MyObject(MyObjectInitializer init) {
        my_x = init.x;
        my_y = init.y;
        my_z = init.z;
    }
}

初始化类可能有自己的实用程序,在这种情况下,您可以将其(以及相应的 MyObject 构造函数)公开。

关于java - 允许最终字段采用默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16447037/

相关文章:

java - 静态最终 int v/s 静态 int

java - 在 Java 中向 ArrayList 添加和访问元素时出现问题

java - 正则表达式匹配 7 位数字后跟 ","

java - 超过 READ COMMITTED 锁等待超时

java - 有什么好方法可以让两个不可变对象(immutable对象)互相引用?

java - 实体类和final关键字

java - 使用 Jaxb2 解码复杂类型

java - 验证和编码大型 XML 文件?

java - 是否可以在 Java 中扩展最终类?

java - Java内存模型中局部最终变量的语义?