模型类上反射 toString 中的 java.lang.ClassCastException : [Z cannot be cast to [Ljava. lang.String

标签 java maven reflection

我有一个 java 模型类,我覆盖了 toString 来为我提供自定义 toString。 toString 使用反射来查找字段名称和值,当我通过 ide 在本地运行它时它可以工作。但是,当我通过 mvn 代理运行它时,我似乎总是收到错误:

java.lang.ClassCastException: [Z cannot be cast to [Ljava.lang.String

这是 toString:

@SneakyThrows
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        Class<?> thisClass = Class.forName(this.getClass().getName());
        Field[] aClassFields = thisClass.getDeclaredFields();
        for (Field f : aClassFields) {
            String fName = f.getName();
            fName = fName.startsWith("_") ? fName.substring(1) : fName;
            if (null != f.get(this)) {
                if (f.get(this) instanceof String || f.get(this) instanceof List) {
                    sb.append(getVariableNameStr(fName, f.get(this).toString()));
                } else {
                    StringBuilder stringArrayStr = new StringBuilder();
                    for (String s : (String[]) f.get(this)) {
                        stringArrayStr.append(fName).append(": ").append(s).append(", ");
                    }
                    sb.append(stringArrayStr);
                }
            }
        }
        return sb.toString().substring(0, sb.toString().length() - 2);
    }

代码中失败的行如下:

for (String s : (String[]) f.get(this)) {

为什么本地可以通过,而使用 mvn 却失败? 谁能告诉我这行有什么不正确的地方吗?

需要澄清的是 - 模型类有 3 种类型的字段 - 字符串、列表和字符串数组。错误行出现在字符串数组条目上。

一个

最佳答案

我认为这是由其他一些库或测试套件接触您的代码引起的。或者本地运行和 Maven 之间的配置差异可能会导致您的对象被包装在其他一些代理类中,因为代理类经常被像 spring 这样的框架使用。
您应该通过删除静态和合成字段来过滤掉不属于对象的字段。正如我在评论中所说,[Z 是一个 boolean[] 字段,因此您肯定会在这里获得一些额外的字段。

此外,反射已经对性能造成了不良影响,并且您无缘无故地多次重复 field.get 调用。我完全不明白为什么你假设字段是 String[] 类型而不检查它。

public String toString() {
    StringBuilder sb = new StringBuilder();
    Class<?> thisClass = this.getClass();
    Field[] aClassFields = thisClass.getDeclaredFields();
    for (Field f : aClassFields) {

        //skip static and synthetic fields:
        if (f.isSynthetic() || Modifier.isStatic(f.getModifiers())) continue;
        // get value only once: 
        Object value = f.get(this);

        String fName = f.getName();
        fName = fName.startsWith("_") ? fName.substring(1) : fName;
        if (value != null) { // and use this value here
            if (value instanceOf String[]) {
                StringBuilder stringArrayStr = new StringBuilder();
                for (String s : (String[]) value) { // and here
                    stringArrayStr.append(fName).append(": ").append(s).append(", ");
                }
                sb.append(stringArrayStr);
            } else {
                sb.append(getVariableNameStr(fName, value.toString()));
            }
        }
    }
    return sb.toString().substring(0, sb.toString().length() - 2);
}

我还重新排序了 ifs 以首先处理 String[] 情况,并对其余可能的对象使用简单的通用 toString,因为这似乎是您的情况。

此外,生成正常的 toString 方法或使用 apache commons 中的一些库(如 ToStringBuilder)也是更好的解决方案。因为看起来您根本不需要在这里使用反射。

关于模型类上反射 toString 中的 java.lang.ClassCastException : [Z cannot be cast to [Ljava. lang.String,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59841007/

相关文章:

java - APDU 命令中的负数

java Android 反射

C++ 反射指南/教程

java - Spring Boot 应用程序已启动,但 POST 请求始终返回 "not found"

xml - 单个文件的 Maven 资源过滤

java - maven如何进行Jar下载?

c# - 如何通过反射从单例类中获取实例

java - Selenium Chrome webdriver 异常

java.lang.NullPointerException :at com. mysql.jdbc.ResultSet.buildIndexMapping

java - 如何使用 gcj 单独编译文件?