Java 使用反射设置值时遇到的问题

Java 使用反射设置值时遇到的问题,java,Java,我使用反射将字段值从类A的对象复制到类B的对象。 然而,A中的方法返回数字,其中B中的as setter需要较长的时间。是否有任何通用方法可以设置该值。正如预期的那样,现在我得到了illegalArgumentException:参数类型不匹配 class a { Number value1; Number value2; public Number getValue1(){return value1;} public Number getValue2(){ret

我使用反射将字段值从类A的对象复制到类B的对象。 然而,A中的方法返回数字,其中B中的as setter需要较长的时间。是否有任何通用方法可以设置该值。正如预期的那样,现在我得到了illegalArgumentException:参数类型不匹配

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;}

}

不确定我的问题是否不清楚。

你不能用“通用”的方式来做这件事,因为
数字可以是
浮点数、
字节等。

你可以这样做

b.setValue2(a.getValue2().longValue());
但是如果
a.value2
实际上不是一个整数(例如,它是一个
Double
和一个分数分量),这将丢失数据

相应地

b.setValue1(a.getValue1().doubleValue());
编辑 好的,我想我已经了解你的情况了。这是一个肮脏的方式去做你想做的事。基本上,您需要有一个转换方法,该方法将根据所选的类将一个数字转换为另一个数字。从
方法
本身获得的类。所以会是这样的:

   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;
   }
publicstaticvoidmain(字符串[]args)引发异常{
A=新的A();
a、 setValue1(1.0);
a、 设定值2(5);
B=新的B();
方法[]方法=b.getClass().getMethods();
用于(方法m:方法){
如果(m.getName().equals(“setValue2”)){
m、 调用(b,transform(a.getValue2(),m.getParameterTypes()[0]);
}
}
System.out.println(b.getValue2());
}
私有静态数字转换(数字n,类到类){
if(toClass==Long.class){
返回n.longValue();
}else if(toClass==Double.class){
返回n.doubleValue();
}
//与此相反,你应该彻底处理其他案件
返回null;
}

否则,您会在上面得到
IllegalArgumentException
的原因是,对于
a
value2
没有设置为
Long
,而是设置为
整数。它们是不相交的类型。如果
a.value2
实际设置为Long,则不会出现该错误。

您需要进行转换:

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

使用自动装箱可以更有效地执行此操作。

@icon666:您如何调用该setter,以至于您不知道正在调用哪个setter?@icon666那么您是否有多个setter?自动装箱与否,您至少应该使用
Long.valueOf(…)
。并检查它是否已经很长,可以简单地强制转换(Long)@Peter Lawrey我认为通过
instanceof
if-else
进行运行时类型识别比始终调用“virtual”方法
longValue
要昂贵得多。嗯,这基本上是我已经说过的,OP已经说过的对他/她不起作用。@fortran:我认为它调用的方法并不昂贵,它可能会创建一个不必要的对象。取决于值的范围和长缓存的大小。如果您的代码与您的问题相对应,那就好了。这里没有任何getter或setter。顺便说一句:我建议您使用double和long等原语,除非您知道需要对象。