我正在为二进制文件格式编写一个解析器。我创建了类来表示我正在阅读的反序列化结构,我想在其中使用 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_y 和 my_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/