4

Is there any way to initialize a data structure to constant values in Java? I've searched high and low and can't find any such technique. I specifically want to initialize a class which contains mixed data types, such as String and int.

class xyz {
      String a;
      int    b;
}

static final xyz example1 = { "string value", 42 };    // This doesn't work.

static final xyz[] example2 = { { "value a", 42 }, { "value b", 43 } };  // this also doesn't work

I can initialize arrays of String, even two-dimensional arrays of String, but for some reason I cannot initialize a record structure or an array of record structures. I do this routinely in Delphi and find it very difficult to live without this feature.

Okay, I've been programming for about 40 years, so I am not exactly a newbie. I need to know if something like this is possible. I do want the constant data embedded in my app, not read in from a file, and using assignment statements to set up the data kind of defeats the purpose of declaring them as constants (final).

Thanks for any suggestions or comments. I really would like to find a good solution to this problem as I have a lot of Pascal code to convert to Java and I don't want to have to redesign all the data structures.

user1698044
  • 41
  • 1
  • 2

4 Answers4

9

If you don't want to use a constructor or a static block as proposed in other answers, you can use the double brace initialization syntax:

static final xyz example1 =
  new xyz() {{ a = "string value"; b = 42; }}; 

Note that it creates an anonymous class.
Your second example would look like:

static final xyz[] example1 = new xyz[] {
  new xyz() {{ a = "value a"; b = 42; }},
  new xyz() {{ a = "value b"; b = 43; }}
};

However, if you have access to the xyz class, adding a constructor that takes two parameters would be more readable and (slightly) more efficient.

vharron
  • 1,138
  • 11
  • 20
assylias
  • 321,522
  • 82
  • 660
  • 783
  • That example seems to compile fine, but I still don't see how to extend the syntax to create an array of records of the class xyz. Where do I put the [] to make my second example work. Pardon me if I am missing the obvious. Can you show me one example of how to do the array based on the double brace initialization syntax? Can I initialize the fields of the record in arbitrary order or leave out some of the fields and have them assigned default values? – user1698044 Sep 26 '12 at 00:59
  • 1
    Thanks! I'll try that in the morning. It's about 3 AM here! – user1698044 Sep 26 '12 at 07:55
  • 1
    Your method works fine for me! Thanks. I will consider using the constructor method as an alternative, but this approach matches the Delphi code most closely in syntax, for better or worse, leading to less work converting Delphi Pascal to Java. Efficiency is important, of course, but readability is also a factor, although I am currently the only one who reads my code! – user1698044 Sep 26 '12 at 14:40
3

One way is write constructor for xyz class to achieve what you want.

class xyz {
      String a;
      int    b;

         xyz(String tempStr, int tempInt)
              {
            this.a = tempStr;
            this.b = tempInt;
             }
}

static final xyz example1 = new xyz("String value",  42);
kosa
  • 65,990
  • 13
  • 130
  • 167
0

You can either write a constructor xyz(String,int) or use the default constructor and initialize the values in a static block:

static final xyz example1 = new xyz();
static { 
  example1.a = "string value";
  example1.b = 42;
}

Note: you should have access to the fields in the initializing class.

Also note: if xyz is an inner class - you will probably need to declare it as static for the above code to work.


P.S. The java convention is using an upper case letter as the first letter in a class name, so it should probably be renamed to Xyz

kosa
  • 65,990
  • 13
  • 130
  • 167
amit
  • 175,853
  • 27
  • 231
  • 333
0

You can use Enums for this

enum xyz {
    VALUE_A("value a", 42), VALUE_B("value b", 43);

    String a;
    int b;

    xyz(String str, int value) {
        a = str;
        b = value;
    }

    static EnumSet<xyz> bothValues = EnumSet.of(xyz.VALUE_A, xyz.VALUE_B);
}
Amit Deshpande
  • 19,001
  • 4
  • 46
  • 72
  • 1
    My real code is more complex and has a lot more fields, some of them enums, but I just picked a simple example with a String and an int in order to have something to talk about. Thanks for your answer and all of the others. I am specifically trying to avoid syntax that looks like a whole bunch of separate assignment statements! – user1698044 Sep 26 '12 at 01:20