此反射代码中的错误是什么?



不懂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()将返回intlong等。

初始答案:您需要使该字段可访问: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)你没有发布你得到的实际异常。它会提供更多的细节吗?

您需要给我们"this"类-不仅仅是set方法-我们至少需要看到字段定义

您使用的是哪个java版本?请记住,自动装箱工作在5.0版本以上。根据异常细节,似乎您正在尝试将长对象值分配给长(本机)值。你可以试试这个:

field.setLong(this, Long.valueOf(item.getValue()[0]).longValue());

item.getValue()[0]为长值时使用field.set(this,Long.valueOf(item.getValue()[0]));

相关内容

  • 没有找到相关文章

最新更新