0

i am using reflection to copy values of fields from object of Class A to object of Class B. However method in A returns Number, where as setter in B requires Long. Is there any generic way i could set the value. As of now as expected i get illegalArgumentException: argument type mismatch

class a
{
    Number value1;
    Number value2;
    public Number getValue1(){return value1;}
    public Number getValue2(){return value2;}

}

class b
{
    Double value1;
    Long   value2;
    public void setValue1(Double value){this.value1 = value;}
    public void setValue2(Long value){this.value2 = value;}

}

Not sure if my question is unclear.

2
  • 1
    It would be good if your code corresponded to your question. You don't have any getters or setters here. Commented Dec 9, 2010 at 17:16
  • BTW: I suggest you use primitives like double and long, unless you know you need an object. Commented Dec 9, 2010 at 19:57

3 Answers 3

1

You could do

b.setValue2(a.getValue2().longValue());

But if a.value2 isn't actually an integer (e.g. it's a Double with a fractional component) this will lose data.

Correspondingly

b.setValue1(a.getValue1().doubleValue());

Edit

Ok I think I've got a grasp on your situation. Here's a dirty way to go about what you want to do. Basically you need to have a transform method which will transform a Number into another Number based on a chosen class. That class you get from the Method itself. So it will be something like this:

   public static void main(String[] args) throws Exception {
      A a = new A();
      a.setValue1(1.0);
      a.setValue2(5);

      B b = new B();

      Method[] methods = b.getClass().getMethods();
      for ( Method m : methods ) {
         if ( m.getName().equals("setValue2") ) {
            m.invoke(b, transform(a.getValue2(), m.getParameterTypes()[0]));
         }
      }
      System.out.println(b.getValue2());
   }

   private static Number transform(Number n, Class<?> toClass) {
      if ( toClass == Long.class ) {
         return n.longValue();
      } else if ( toClass == Double.class ) {
         return n.doubleValue();
      }
      //instead of this you should handle the other cases exhaustively
      return null;
   }

The reason you would otherwise get an IllegalArgumentException in the above is because with a, value2 is not being set to a Long, it's being set to an Integer. They are disjoint types. If a.value2 was actually set to be a Long instead, you wouldn't have that error.

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

2 Comments

@icon666: How are you invoking that setter such that you don't know what setter you're invoking?
@icon666 so do you have multiple setters?
1

You need to do the conversion:

// get the Number 'number'
Long l = new Long(number.longValue());
// store the Long

You could do it even more efficiently using autoboxing.

11 Comments

Autoboxing or not, you should at least be using Long.valueOf(...).
And check its not a Long already which can be simply cast (Long).
@Peter Lawrey I think runtime type identification via instanceof and having an if-else would be more expensive that calling always the "virtual" method longValue.
Hmm, this is basically what I already said, which the OP already said doesn't work for him/her.
@fortran: I don't think it's calling the method that's expensive, it's potentially creating an unnecessary object. Depends on the range of values and the size of the Long cache.
|
0

You can't do this in a 'generic' way, because a Number could be a Float, Byte etc.

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.