java - Allowing final fields to take default values -
i writing parser binary file format. have created classes represent deserialized structures reading, in use final variables hold extracted data.
class myobject { final int my_x; final int my_y; final int my_z; }
the bump running presence of fields depends on flags being set. example:
myobject(inputstream is) { my_x = in.read(); if (my_x == 1) { my_y = in.read(); if (my_y == 1) { my_z = in.read(); } } }
however, gives me error because my_y , my_z may not initialized. these conditionals can 5-6 levels deep, , don't want track fields may not read @ each level of branch tree. complication that, based on flags, there may subobjects handle same pattern top-level structures.
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(); } } }
is there way make fields final without twisting code handle each possible combination of flags?
use local variables , assign final
fields @ end of constructor.
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; }
alternatively (as jon skeet suggests in comment), use static factory method computes appropriate values no-default constructor:
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); }
a third approach define initializer object class:
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; } }
the initializer class may have utility on own, in case make (and corresponding myobject
constructor) public.
Comments
Post a Comment