tags:

views:

91

answers:

4

Looking at some code cleanup and I was wondering the best way to deal with this:

Have a class with some private variables like:

myBool1, myBool2, myBool3
myInt1, myInt2, myInt3
myString1, myString2, myString3

What's the best way to do a getter function that is generic to the return value? So if I do a call to the getter with something like:

myNewBool=<blah>.get("myBool1")
myNewString=<blah>.get("myString2")
myNewInt=<blah>.get("myInt3") 

Anyone have any suggestions?

+6  A: 

You can't really have a generic getter if you don't know what you want to get, for example :

boolean myNewBool= get("myString1");

If get returns something, but you don't really know if this something is compatible with a boolean, and terrible things could happen.

You could try this:

public <T> get(String element){
    return (T) elementToGet;
}

But you would have to specify the return type when you call the get method.

String element = myObject.<String>get("element");

Here are the bad sides :

  • You can't work directly with primitives
  • You can have a lot of ClassCastException
  • If you misspell an attribute name you won't see it until you run it
  • You don't expose a nice public API, people would have to know evert possible attribute to use it, and as said above, a misspelled attribute (or an inexistant one) wouldn't be seen until runtime.
  • You have to know the return time and type it each time you use your method
  • You would have to type a really long (and smelly) code in your get method either to use each possible attribute (if you still want have some private and not accessible) or worse, use reflection to find the right attribute.

So definitively not a good idea.

What you can do instead is using the good old getters//setters and if there is a lot of them, generate them with your IDE.

Another way would be to use the project lombok.


Resources :

On the same topic :

Colin Hebert
I'm actually thinking that get("myWhatever") is not what I want to do at all?
pn1 dude
lombok looks interesting. Thanks for all the information. I'm feeling that my current verbose getter/setter for each var is not only standard but really needs not be replaced with a "new" way.
pn1 dude
BTW thanks for the Code block, it was cool to consider the possibilities with that.
pn1 dude
A: 

This is really a terrible idea. I'm not sure why creating a getter/setter for each private variable is a problem, but passing around strings that map to a variable's symbolic name would be hard to maintain and confusing. You don't need this to be generic; each variable represents a different quantity and they should be accessed as such.

Ed Swangren
Yeah, I currently have getter and setters for each one and this a long block of getters/setters. I was trying to think of a way to cut this down. Its not a problem and I was really trying to talk about it.
pn1 dude
I was talking about it too ;). I just don't see a problem, and the proposed method makes the code harder to understand and to maintain.
Ed Swangren
+3  A: 

First you should ask what would be the pros and cons of such a solution.

Pros:

  • One method instead of many

Cons:

  • Non-intuitive to the users of your class (classical getters are more common)
  • You cannot have an overload that only differs by a return type, therefore you will have to have methods like getBool, getInt etc.
  • It's slower - you have to pass the string, check for validity, do a lookup in a map...

The only advantage of your proposed solution would be not repeating the get()/set() code. However, as these methods are usually generated by your IDE and contain only a single-line command, I wouldn't see that as a big problem.

To answer your actual question - you can create a HashMap with name-attribute mapping. Alternatively, you may use Java reflection to access the attributes. The second solution is more general but also harder to write.

dark_charlie
Thanks for the exploration. I think the key thing here is NOT doing things outside of what is actually intuitive to others. Big important thing to consider! So important.
pn1 dude
A: 

It wouldn't be clean up but mess up. I'd either created 3 getter methods for the fields or redesign it completely. But calling a function, with a name of a field to return, as an argument can bring nothing good.

When you code, you must be refactoring your code for all the time you are coding. But not like this. Solution is delegating logic to another class, wrapping code into more utilizable methods or changing and simplifying domain objects...

lisak