问题
Curious if anybody has considered using EnumMap in place of Java beans, particularly "value objects" (with no behavior)? To me it seems that one advantage would be that the name of a "property" would be directly accessible from the backing Enum, with no need for reflection, and therefore I'd assume it would be faster.
回答1:
It may be a little faster then using reflection (I didn't measure it, didn't find any metrics in Google either); however there are big disadvantages to this approach:
You're losing type safety. Instead of
int getAge()
andString getName()
everything isObject get(MyEnum.FIELD_NAME)
. That'll provide for some ugly code and run-time errors right there.All the javabean niceties we've come to love and enjoy (for example, property-level annotations) are gone.
Since you can have NO BEHAVIOR AT ALL, the applicability of this approach seems rather limited.
The bottom line is - if you really truly need that alleged :-) boost in performance (which you'll have to measure to prove it exists) this may be a viable approach under very specific circumstances. Is it a viable alternative to javabeans at large? Most certainly not.
回答2:
A bean is meant to be mutable, hence the setter methods. EnumMap is comparable in speed to using a HashMap with integers as the Key, but are Keys are Immutable. Beans and EnumMaps serve two different purposes. If all of the Keys are known at design time and are guaranteed to never change, then using an EnumMap will be fine.
Updating a bean is much simpler than changing the backing Enum of the EnumMap with much less chance of creating errors downstream in the code.
回答3:
I wrote a Record class that maps keys to values and works by delegating to a fully synchronized EnumMap. The idea is that a Record can get new fields at runtime whereas the Bean can't. My conclusion is that with this flexibility comes a performance hit. Here's a run comparing the Record class to a fully synchronized Bean. For 10 million operations:
Record set(Thing, a) 458 ms
Bean setThing(a) 278 ms
Record get(Thing) 398 ms
Bean getThing 248 ms
So, there is something to gain in knowing your data objects and writing a class that models them statically. If you want to have new fields padded on to your data at runtime, it will cost you.
回答4:
I don't understand how you can remove 'class profileration' with EnumMaps. Unless you have a generic enum with 20-odd properties to reuse for every 'bean', you're still inventing an enum to use for each enum map, e.g.
public enum PersonDTOEnum {
A, S, L;
}
as opposed to
class Person {
int a;
int s;
String l;
// getters + setters elided
}
Not to mention that everything is a String now.
回答5:
I had not previously specified this, but I am working with a ResultSet. Therefore I want to provide this answer for the sake of completeness.
Commons/BeanUtil's "RowSetDynaClass" could be the happy medium between the excessive boilerplate associated with concrete beans, and the limitations of EnumMap
来源:https://stackoverflow.com/questions/1359157/might-enummap-be-considered-a-reasonable-alternative-to-java-beans