3

Say I have the following class:

class Foo
{
   public String bar;
   public String baz;
}

And I have the following code, in another class:

Foo foo = new Foo();
String[] properties = {"bar", "baz"};
String[] values = {"barValue", "bazValue"};

Is it possible to iterate over the properties array and use that to set the values of Foo? E.g something like:

for (int i = 0; i < properties.length; i++)
{
  foo[ properties[i] ] = values[i];
}

Is something like the above possible?

7
  • 1
    But why without reflection restriction? Commented Oct 13, 2013 at 4:24
  • 1
    just use a HashMap. Commented Oct 13, 2013 at 4:24
  • no that's not possible without reflection. Commented Oct 13, 2013 at 4:26
  • I believe that Roippi's solution is the only one, for what you are describing, unless you want to write a custom function that accepts two arguments, and tests the property to assign them to the proper variable. Commented Oct 13, 2013 at 4:26
  • My example is simplistic, obviously my class will have other methods, or I'd use a HashMap. Commented Oct 13, 2013 at 4:31

2 Answers 2

6

Is something like the above possible?

No.

With the properties as you have defined them, your only choices are:

  • writing or generating Java code (or bytecodes) to refer to the fields a foo.bar or foo.baz, or

  • use reflection.

If you want dynamic properties, use a Map object; e.g. a HashMap<String, String>.


As to your illustrative example, that won't / can't work because:

  • regular object fields cannot be indexed like an array, and
  • unlike C++, Python and other languages, Java doesn't support ad-hoc overloading of any of the core language constructs (apart from methods).

Java is not a dynamic language that supports this kind of thing. You need to learn to live with what it can offer you ... or use a different language.


You commented thus:

Reflection is supposed to be bad for performance.

Well yes, but it is relative. Accessing or updating a field reflectively is likely to be 10 to 100 times slower than accessing/updating it using normal Java code. However, if you are only doing this occasionally, the performance overhead may not be relevant. If it does turn out to be an issue, then your options include hand-writing, or generating the code. For example:

public class Foo
{
   public String bar;
   public String baz;

   public void setNamedProperty(String name, String value) {
       switch (name) {
       case "bar": 
           bar = value;
           break;
       case "baz": 
           baz = value;
           break;
       default:
           throw new IllegalArgumentException("Unknown property name");
       }
   }
}

For what it is worth, that code is going to be about as time efficient as setting a dynamic property in a language that supports dynamic properties. (And I suspect it will be more space efficient, given that dynamic properties are typically implemented using native coded hash tables.)

Sign up to request clarification or add additional context in comments.

2 Comments

I am not getting "writing or generating Java code (or bytecodes) to refer to the fields a foo.bar" ??? Could you please elaborate....
@KanagaveluSugumar - for example, "write a setter method and call it". Note that these are alternatives to dynamic properties.
1

You can use Introspection, and it is much better a way when you face Java Beans.

Cons are:

  • It will call getter/setters if they are present, or will access fields directly if there are no getter/setters and fields are public.
  • You can iterate over properties, because it gives you an array of PropertyDescriptors.
  • It support BeanInfo classes,
    • so you can configure your bean properties
    • define accessor/mutators with different naming convention (not getter or setter)
  • You can use libraries like Apache Commons BeanUtils or Spring BeanWrapper API.

For more information look at java.beans.Introspector javadocs.

By the way as far as I know Interospection is built upon reflection, so it uses reflection itself.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.