java .lang.ClassCastException: [Z не может быть приведен к [L java .lang.String в отражающей toString в классе модели - PullRequest
0 голосов
/ 21 января 2020

У меня есть класс модели в 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 типа полей - String, List и String array. Строка с ошибкой возникает в записях массива String.

A

Ответы [ 2 ]

2 голосов
/ 21 января 2020

Я предполагаю, что это вызвано тем, что некоторые другие библиотеки или наборы тестов касаются вашего кода. Или некоторое различие в конфигурации между локальным прогоном и maven может привести к тому, что ваши объекты будут обернуты в некоторые другие прокси-классы, поскольку прокси-классы часто используются в таких средах, как spring.
Вы должны отфильтровать поля, которые не являются частью объекта, с помощью удаление полей stati c и syntheti c. Как я уже говорил в комментарии, [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);
}

Я также переупорядочил if для обработки String[] case в первую очередь и использовал простой c toString для остальных возможных объектов, поскольку это, кажется, ваш случай.

Также было бы гораздо лучшим решением просто сгенерировать обычный метод toString или использовать некоторые библиотеки, такие как ToStringBuilder из apache commons , Поскольку это не похоже на то, что вам вообще нужно использовать отражения здесь.

0 голосов
/ 21 января 2020

[Z означает boolean[] - не String[]. Таким образом, поле имеет тип boolean [].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...