不懂Java又让我吃亏了。我有以下成员函数:
protected void setData(Map<String, String[]> data) {
Class thisClass = this.getClass();
for(Map.Entry<String, String[]> item : data.entrySet()) {
try {
Field field = thisClass.getDeclaredField(item.getKey());
try {
if(field.getType().getName().equals("java.lang.Long")) {
// EXCEPTION HERE!!!
field.setLong(this, Long.valueOf(item.getValue()[0]) );
}...
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} catch (NoSuchFieldException e) {
// Skip this field...
continue;
}
}
}
我一直得到一个IllegalArgumentException,我不完全明白为什么。有人能提供一些见解吗?
该函数接受一个映射,并对其进行迭代,并通过检查"this"上是否存在字段来将值赋给"this",如果存在,则尝试调用field.set()
。
setLong(..)
尝试设置一个原始值,您的字段是java.lang.Long
。对于非原语总是使用set(..)
方法。对于原语,getType().getName()
将返回int
、long
等。
初始答案:您需要使该字段可访问:field.setAccessible(true)
根据field. set()文档,如果您试图设置()一个值到一个字段中,该值不能分配给该字段,您会得到一个IllegalArgumentException
使用下面的代码,我只得到非法的ARGUMENT异常-没有非法的访问异常:
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public class Asdf2 {
private Long long1;
Long long2;
protected Long long3;
private long long4;
Long long5;
protected long long6;
protected void setData(Map<String, String[]> data) {
Class thisClass = this.getClass();
for (Map.Entry<String, String[]> item : data.entrySet()) {
try {
Field field = thisClass.getDeclaredField(item.getKey());
try {
field.setAccessible(true);
if (field.getType().getName().equals("java.lang.Long")) {
field.setLong(this, Long.valueOf(item.getValue()[0]));
} else {
field.set(this, item.getValue()); // EXCEPTION HERE!!!
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
} catch (NoSuchFieldException e) {
// Skip this field...
continue;
}
}
}
@Override
public String toString() {
return "Asdf2["
+ "long1=" + long1
+ ",long2=" + long2
+ ",long3=" + long3
+ ",long4=" + long4
+ ",long5=" + long5
+ ",long6=" + long6
+ "]";
}
public static void main(String[] args) {
Map<String, String[]> data = new HashMap<String, String[]>();
data.put("long1", new String[] { "1" });
data.put("long2", new String[] { "2" });
data.put("long3", new String[] { "3" });
data.put("long4", new String[] { "4" });
data.put("long5", new String[] { "5" });
data.put("long6", new String[] { "6" });
Asdf2 test = new Asdf2();
test.setData(data);
System.out.println(test);
System.out.println("Done!");
}
}
我的评论是:
1)如果它是一个Long,你把值的第一个元素(这是一个数组)放入该字段,但否则你把整个数组-这只会工作,如果字段也是字符串数组
2)你没有发布你得到的实际异常。它会提供更多的细节吗?
您使用的是哪个java版本?请记住,自动装箱工作在5.0版本以上。根据异常细节,似乎您正在尝试将长对象值分配给长(本机)值。你可以试试这个:
field.setLong(this, Long.valueOf(item.getValue()[0]).longValue());
当item.getValue()[0]
为长值时使用field.set(this,Long.valueOf(item.getValue()[0]));