3

I am building an application for a client and I am in the situation where I need to have the ability to reference a field value via a string, i.e the users uses a string to define which field they want to change the value of, this is part of an abstract framework so technically I don't know the name of the fields they desire to change. Of course I could do this using hash maps, but I am considering using java reflection as this allows the fields to stay as fields of the object rather than the values being coded into a hash map. I have used reflection for my own personal work, but I was wondering if using Java reflection is actually bad practice, and I should stick to the hashmap methodology.

(Any other suggestions for solving the design problem described are also appreciated)

Thanks

Sam Palmer
  • 1,675
  • 1
  • 25
  • 45
  • 1
    I rephrase your question: "Is it a bad practise, to manipulate objects, so they won't work as they intended to?" I thibk you can answer this. – Bálint Apr 15 '16 at 10:16
  • erm no it is slightly different, because the application is actually based on setting the values of the object which are intended to be changed. The issue is that they need to be referenced via their string name – Sam Palmer Apr 15 '16 at 10:18
  • Reflection is very slow, so it's not a good thing to use. Also, yes variables are there to get chabged, but what if you changed one of the variable's value to something unexpected? – Bálint Apr 15 '16 at 10:18
  • 1
    In Android it is a bad idea, cuz proguard wont work on this. – Enzokie Apr 15 '16 at 10:20
  • yeah thats my other concern, the problem would be solved if I could use pointers with a hashmap with the pointer pointing to the field address, damn you java sometimes – Sam Palmer Apr 15 '16 at 10:20
  • so how does the user know the names? are you using reflection first to get a list of names they can change and then also to allow changes to be made? though if it's a pure 'best practice' question then the answer's pretty much 'no' – Wain Apr 15 '16 at 10:20
  • 2
    Avoid reflection as much as possible unless it is the last option for you. – Enzokie Apr 15 '16 at 10:22
  • @Wain so the user knows the names of the fields, basically we are building an optimisation framework where you supply a list of the names of the parameters (fields) you wish to optimise – Sam Palmer Apr 15 '16 at 10:22
  • @neferpitou it seems to be the smoothest solution in this case, but I know not the most ideal :( – Sam Palmer Apr 15 '16 at 10:24
  • 1
    It seems you've got most of the warnings already, so I'll just throw in that Sun didn't add reflection to the Java language, just to make us able to shoot our heads off (or shoot ourselves in the foot perhaps). Sometimes it's just the right tool for the job. It's hard to say from the question, whether or not it is in your case though. – Harald K Apr 15 '16 at 10:37

2 Answers2

9

The question itself is opinion based, although I believe most will agree that you can't just say "reflection is bad". Sometimes it's the only way, which is why a lot of libraries use reflection. Sometimes it's not the only way, but a workaround would be even worse. Sometimes it's not the only way, and not the easiest way, but the developer is far too amazed at the power of reflection to think straight.

Except for that last one there are plenty of valid reasons to consider reflection as a solution.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
0

Personally reflection makes me sad, and in my experience there is almost always a better way. In the problem you described, setting variables based on a string i'd consider going with your hashmap idea which would reference variables via a string key which seems like exactly what you are describing. If you need the ability to reference values that do not exist you could also include factory methods to create variables when no key exists and then add to the map, if you are wrapping the objects then they will be passed by reference to avoid the problem you describe but this depends on the implementation (eg using Integer class etc for auto boxing if you are referencing primitives) Together this would allow for a much tighter and well defined implementation rather than reflecting values here there and everywhere. Apologies for the anti-reflection bias! Hope this helps.