Java 使用反射设置值时遇到的问题
我使用反射将字段值从类A的对象复制到类B的对象。 然而,A中的方法返回数字,其中B中的as setter需要较长的时间。是否有任何通用方法可以设置该值。正如预期的那样,现在我得到了illegalArgumentException:参数类型不匹配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
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等原语,除非您知道需要对象。