How do I access static variables in an enum class without a class instance?
I have some code that processes fixed length data records. I've defined the record structures using java enums. I've boiled it down the the simplest example possible to illustrate the hoops that I currently have to jump through to get access to a static variable inside the enum. Is there a better way to get at this variable that I'm overlooking? If you compile and run the code, it converts each string into an XML chunk. I've done the XML manually so that the example is simpler, but my real code uses Java DOM.
EDIT: I've updated the code to a more complete example that I think better shows what I'm trying to do.
class EnumTest
{
public static void main(String args[])
{
System.out.println( parse("ABC", RecordType1.class) );
System.out.println( parse("ABCDEF", RecordType2.class) );
}
private interface RecordLayout {
public int length();
}
private enum RecordType1 implements RecordLayout {
FIELD1 (2),
FIELD2 (1),
;
private int length;
private RecordType1(int length) { this.len开发者_如何转开发gth = length; }
public int length() { return length; }
public static int RECORD_LEN = 3;
}
private enum RecordType2 implements RecordLayout {
FIELD1 (5),
FIELD2 (1),
;
private int length;
private RecordType2(int length) { this.length = length; }
public int length() { return length; }
public static int RECORD_LEN = 6;
}
private static <E extends Enum<E> & RecordLayout> String parse(String data, Class<E> record) {
// ugly hack to get at RECORD_LEN...
int len = 0;
try {
len = record.getField("RECORD_LEN").getInt(record);
}
catch (Exception e) { System.out.println(e); }
String results = "<RECORD length=\"" + len + "\">\n";
int curPos = 0;
for (E field: record.getEnumConstants()) {
int endPos = curPos + field.length();
results += " <" + field.toString() + ">"
+ data.substring(curPos, endPos)
+ "</" + field.toString() + ">\n";
curPos = endPos;
}
results += "</RECORD>\n";
return results;
}
}
How about this code in Java 8?
// Java 8
public class EnumTest {
public static void main(String args[]) {
System.out.println(parse("ABC", RecordType1.class));
System.out.println(parse("ABCDEF", RecordType2.class));
}
private interface RecordLayout {
public int length();
public static <E extends Enum<E> & RecordLayout> int getTotalLength(Class<E> e) {
int total = 0;
for (E e1 : e.getEnumConstants()) {
total += e1.length();
}
return total;
}
}
private enum RecordType1 implements RecordLayout {
FIELD1(2),
FIELD2(1),;
private int length;
private RecordType1(int length) {
this.length = length;
}
public int length() {
return length;
}
}
private enum RecordType2 implements RecordLayout {
FIELD1(5),
FIELD2(1),;
private int length;
private RecordType2(int length) {
this.length = length;
}
public int length() {
return length;
}
}
private static <E extends Enum<E> & RecordLayout> String parse(String data, Class<E> record) {
int len = RecordLayout.getTotalLength(record);
String results = "<RECORD length=\"" + len + "\">\n";
int curPos = 0;
for (E field : record.getEnumConstants()) {
int endPos = curPos + field.length();
results += " <" + field.toString() + ">"
+ data.substring(curPos, endPos)
+ "</" + field.toString() + ">\n";
curPos = endPos;
}
results += "</RECORD>\n";
return results;
}
}
Does RecordType1.LEN
not work?
I don't have a Java environment at hand right now, so I'm preparing to wipe egg from my face, but since enum Foo
is equivalent to class Foo extends Enum<Foo>
I cannot see why you can't just access the static members in the standard way.
Edit: if you want to access static members dynamically, then this isn't going to work as you have to access static members based on the class rather than the instance, that's the point. You should probably do something like this instead, since if the behaviour changes depending on the subtype of the instance, that's exactly the kind of thing an interface is for:
class EnumTest
{
private interface RecordLayout {
public int length();
public int staticLength(); // give this a more meaningful name
}
private enum RecordType1 implements RecordLayout {
...
public static int LEN = 3;
public int staticLength() {
return LEN;
}
}
private enum RecordType2 implements RecordLayout {
...
public static int LEN = 5;
public int staticLength() {
return LEN;
}
}
...
private static String parse(String data, RecordLayout record) {
int len = record.getStaticLength();
System.out.println(len);
...
}
}
As long as you are inside the EnumTest
class, you can access the LEN
field by simply writing:
int len = RecordType1.LEN;
From the outside, it's still difficult.
精彩评论