• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Reflection to set ArrayList attribute

 
Ranch Hand
Posts: 305
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hello All,
I have an instance variable labels which is of type ArrayList. I'm using the Reflection API to dynamically set instance variables, which is no problem, until it comes to labels.

Assume I have a String which contains attribute-value pairs, which is fed to the Reflection mechanism. The String is in the following format:



Essentially, the Reflection mechanism will look up the Field labels and call the set method, however, you see the problem. labels is an ArrayList, and I get an IllegalArgumentException.

I've overloaded my setLabels() to accept a comma-delimited String as follows:



Apparently the Reflection API checks to see the type passed into the setxxx() method matches the instance variable type?

So, my question is, how can I use the Reflection API to set an instance variable which is of type ArrayList?

Thanks!
 
Bartender
Posts: 1844
Eclipse IDE Ruby Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Parse the String and create the ArrayList yourself -- reflection cannot do that. Then you can use the set(Object, Object) method of the Field to set the value of the array list -- set(target, arrayList).

Alternatively, you caould use java.lang.reflect.Method to call your setLabels methods instead of using the java.lang.reflect.Field
[ December 08, 2004: Message edited by: Joel McNary ]
 
Jeffrey Hunter
Ranch Hand
Posts: 305
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks, Joel. I had put a hack on the code before I read your message. Basically, I created another instance variable labelsRawString which, you guessed it, is of type String and represents the comma-delimited String of values. In this case, the Reflection mechanism works as expected. But of course, I'm stuck with an instance variable that serves no other purpose than to receive some data and pass it along to the appropriate instance variable.

Something interesting I did notice. I put some extra logic in the setLabelsRawString(String s) method and found that when called via Reflection, it does not actually get executed?!

For instance, a dreadfully simple example:



When I used Reflection to set the respective instance variable, the message does not print out. Does the Reflection mechanism not use the actual setxxx() methods defined in my class? Or have I just overlooked something?
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Jeff --

setXXX() methods are a convention, and in no way, shape, or form are they ever called automatically by any part of Java, nor are they absolutely tied, explicitly or implicitly, to any instance variable by name or by any other criterion. There is absolutely nothing to keep you from writing



If you set a field via reflection, then the value of the field is set directly. The Reflection API doesn't consider for a moment the existence of any setXXX methods.

Anyway, if you want to call setXXX(), then you actually have two choices. You can use java.lang.reflect.Method, not java.lang.reflect.Field; then you'd have to look up the setXXX() methods specifically.

Alternatively, you seem to want to treat the class like a JavaBean -- a class for which setXXX() and getXXX() methods are specifically intended, by convention to represent properties that you can set and read by calling them. If that's always going to be the case, then instead of using reflection directly, you want to use the java.beans.Introspector class and its associated machinery, which will find all the set/getXXX methods of a class and present them to you in a convenient format for use.
 
Jeffrey Hunter
Ranch Hand
Posts: 305
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ernest Friedman-Hill:

If you set a field via reflection, then the value of the field is set directly. The Reflection API doesn't consider for a moment the existence of any setXXX methods.



Ahh, now it makes perfect sense. Thanks, Ernest. It does appear that this class lends itself to the JavaBean model, so to speak, as it would be handy to initialize its instance variables via introspection. I had not thought of this before -- I was focused on Reflection (a similar idea, but different, as I now see). Perhaps I can get ride of my crude hack and refurnish this class to use the Introspector features.

Thanks again!
 
Onion rings are vegetable donuts. Taste this tiny ad:
a bit of art, as a gift, the permaculture playing cards
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic