How can I go about populating a simple Java object with data from any other arbitrary object?
For example, I can end up with a Document object whose children nodes I can iterate through and I want to set same-named properties in another object with the node’s values.
I work primarily in dynamic languages and I think I am hung up on how this would work in perl or javascript and can’t get my head out of the dynamic gutter long enough to see this clearly.
I know I could do something like (pseudo code)
while (key = nextKey) {
if (key.name == "fooBar") {
object.setFooBar(key.value);
} else if (key.name == "bazQux") {
object.setBazQux(key.value);
}
...etc...
}
But that just doesn’t feel good, and feels awful when the number of properties or complexity increases.
In a dynamic language, i would do something like:
while (key = nextKey) {
object.setField(key.name, key.value);
// or even
object.[key.name] = key.value;
}
where setField could be a dispatch table with code references. I know I don’t have the luxury of every object being a hash by default, but I’m looking for general advice. How would you do it?
A switch/case would be a little better, but java complains about it not enjoying Strings in such statements. Would enums be a solution? </blind stabbing for answers>
I’ve looked into using reflection in order to implement some sort of automatic dispatch table, but that strikes me as being looked down upon and that there has to be a better way.
Thanks for any insight.
Another vote for reflection. What you’re trying to do here is automatically bind untyped String data to typed Java variables. That’s simply going to require reflection.
The reason reflection is “looked down upon” is because generally speaking, blindly binding untyped String data to typed Java variables is “looked down upon”. In many cases it’s better to (for example) have your object explicitly pull out only the data it needs. For example:
You might say, “But now if I add a
sysBizentry to my document, I have to remember to add an extra line to my constructor. In a dynamic language it would Just Work[tm]!” That’s true, but in Java you have to add yoursysBizmember variable, your getters and setters, and all the other logic aroundsysBizanyway, so an extra line in your constructor or deserialization section isn’t all that much of a nuisance. Plus, it makes explicit which parts of the document you care about, so if somebody adds azigBlogentry to the document, it won’t cause problems with your automatic binding (e.g. something that looked likeobject.setField(key, val)) throwing a runtime error about nozigBlogfield existing.All that said, there are times when automatically binding untyped String data to typed Java variables is the right way to go, and reflection is the right tool to use in that scenario. Make sure that automatic binding really is the best choice for the data structures you’ve got, but once you’re sure, there’s no need to hesitate to use reflection just because it’s “looked down upon” or is a slightly more advanced section of the language. That’s exactly what it’s there for.