8

I'm setting public fields of the Object this via reflection. Both the field name and the value are given as String. I use several various field types: Boolean, Integer, Float, Double, an own enum, and a String.

It works with all of them except with a String. The exception that gets thrown is that no method with the signature String.valueOf(String) exists... Now I use a dirty instanceof workaround to detect if each field is a String and in that case just copy the value to the field.

private void setField(String field, String value) throws Exception {
   Field wField = this.getClass().getField(field);

   if(wField.get(this) instanceof String){ //TODO dirrrrty hack
    //stupid workaround as java.lang.String.valueOf(java.lang.String) fails...
    wField.set(this, value);
   }else{
    Method parseMethod = wField.getType().getMethod("valueOf", new Class[]{String.class});
    wField.set(this, parseMethod.invoke(wField, value));
   }
 }

Any ideas how to avoid that workaround?

Do you think java.lang.String should support the method valueOf(String)?

Thanks.

bluish
  • 26,356
  • 27
  • 122
  • 180
fabb
  • 11,660
  • 13
  • 67
  • 111
  • It's worth mentioning that all of these Objects (except enums) have unary String constructors. So you could switch to using those in all cases and only using `valueOf` for your enums, if that seems somehow cleaner. – jasonmp85 May 30 '10 at 14:43

4 Answers4

8

As you've noticed, there is no String.valueOf(String). However, I wouldn't consider your implementation a hack, just recognition of the minor inconsistency in the JDK classes.

For more robust String to Object conversion, you might consider using PropertyEditors, which directly support String to Object conversion - implementation for primitive types and Strings provided by default.) Your parse method will then be consistent, and extendible to handle different types. Better still are the conversion classes in Commons Convert, and Spring 3 Type Converters, as these are focused purely on conversion, and not GUI editing of properties.

mdma
  • 56,943
  • 12
  • 94
  • 128
  • PropertyEditors are in use by Spring, no? They are definitely what you want here, btw. – jasonmp85 May 30 '10 at 14:42
  • Spring does use PropertyEditors, but with Spring 3.x also the new type conversion classes which are "cleaner" than PropertyEditors. – mdma May 30 '10 at 14:48
0

In Case Of String:

Method parseMethod = wField.getType().getMethod("valueOf", new Class[]{Object.class});

wField.set(this, parseMethod.invoke(wField, value));

Awanish Kumar
  • 640
  • 8
  • 15
0

Any ideas how to avoid that workaround?

This largely depends on the implementation of parseMethod.

Do you think java.lang.String should support the method valueOf(String)?

What for? That would be a no-op, simply returning its parameter.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
  • 1
    parseMethod IS valueOf(String). So I didn't implement that by myself. yes, it would be a no-op, but it would make valueOf more general useable IMHO. at least in this case. but maybe there's another option i'm not aware of. – fabb May 30 '10 at 14:32
  • @fabb, it would be usable only in a special case of reflection, so most Java developers would never need it. And IMHO the workaround you show is something one can live with. – Péter Török May 30 '10 at 14:39
0

Do you think java.lang.String should support the method valueOf(String)?

No. It would have almost no value outside of reflection, and reflection shouldn't be encouraged anyway (Effective Java 2nd Edition, Item 53: Prefer interfaces to reflection).

polygenelubricants
  • 376,812
  • 128
  • 561
  • 623
  • 2
    Oh come on, just because Bloch said it doesn't make it true. Reflection is a powerful and wonderful tool. I will concede that this particular instance doesn't seem like its greatest moment, however. – jasonmp85 May 30 '10 at 14:39