Динамически приведен к каждому типу массива - PullRequest
1 голос
/ 21 апреля 2019

Я использую следующий метод для печати всего содержимого пакета в любом возможном случае. Проблема в том, что PMD сообщает как NcssCount, так и CyclomaticComplexity. Я хотел бы улучшить код, чтобы избавиться от предупреждений, а не просто подавить их.

private static String bundleToString(Bundle bundle) {
    StringBuilder out = new StringBuilder("Bundle[");

    if (bundle == null) {
        out.append("null");
    } else {
        boolean first = true;
        for (String key : bundle.keySet()) {
            if (!first) {
                out.append(", ");
            }

            out.append(key).append('=');

            Object value = bundle.get(key);

            if (value instanceof int[]) {
                out.append(Arrays.toString((int[]) value));
            } else if (value instanceof byte[]) {
                out.append(Arrays.toString((byte[]) value));
            } else if (value instanceof boolean[]) {
                out.append(Arrays.toString((boolean[]) value));
            } else if (value instanceof short[]) {
                out.append(Arrays.toString((short[]) value));
            } else if (value instanceof long[]) {
                out.append(Arrays.toString((long[]) value));
            } else if (value instanceof float[]) {
                out.append(Arrays.toString((float[]) value));
            } else if (value instanceof double[]) {
                out.append(Arrays.toString((double[]) value));
            } else if (value instanceof String[]) {
                out.append(Arrays.toString((String[]) value));
            } else if (value instanceof CharSequence[]) {
                out.append(Arrays.toString((CharSequence[]) value));
            } else if (value instanceof Parcelable[]) {
                out.append(Arrays.toString((Parcelable[]) value));
            } else if (value instanceof Bundle) {
                out.append(bundleToString((Bundle) value));
            } else {
                out.append(value);
            }

            first = false;
        }
    }

    out.append(']');
    return out.toString();
}

Я пытался разделить код на две части, используя следующую логику, но NcssCount и CyclomaticComplexity только что перешли на новый метод, который выполняет все приведения массива.

if (value != null && value.getClass().isArray()) {
   // the new method to call all the array casts
   newMethodThatSuffersFromTheSameProblem(out, value);
} else if (value instanceof Bundle) {
    out.append(bundleToString((Bundle) value));
} else {
    out.append(value);
}

Можно ли как-нибудь выполнить динамическое приведение к каждому типу массива?

if (value != null && value.getClass().isArray()) {
   out.append(Arrays.toString((<cast-to-class-array-[]>) value));
}

Я также пытался out.append(Arrays.toString(value.getClass().cast(value)));, но получает ошибку компиляции Cannot resolve method 'toString(capture<? extends java.lang.Object>)'

Ответы [ 2 ]

4 голосов
/ 21 апреля 2019
} else if (value instanceof String[]) {
  out.append(Arrays.toString((String[]) value));
} else if (value instanceof CharSequence[]) {
  out.append(Arrays.toString((CharSequence[]) value));
} else if (value instanceof Parcelable[]) {
  out.append(Arrays.toString((Parcelable[]) value));

Эти 3 if с можно заменить одним

} else if (value != null && value.getClass().isArray())
  out.append(Arrays.toString((Object[]) value));

. В остальном вы можете задать статический Map<Class, Function<Object, String>> convertors и предварительно заполнить его как

convertors.put(int[].class, value -> Arrays.toString((int [])value));
...
* 1009.* и затем используйте
Function<Object, String> convertor = convertors.get(value.getClass());
if (convertor != null) {
  out.append(convertor.apply(value));
} else ...

ДЛЯ СТАРЫХ АНДРОИДОВ, ГДЕ ЛАМБДА НЕ ДОСТУПНЫ

interface ToString { String convert(Object object); }
...
static Map<Class, ToString> convertors = new HashMap();
convertors.put(int[].class, new ToString() { public String convert(Object value) { return Arrays.toString((int [])value); }}); 
...

, а затем используйте

ToString convertor = convertors.get(value.getClass());
if (convertor != null) {
  out.append(convertor.convert(value));
} else ...
0 голосов
/ 25 апреля 2019

Я не могу проверить это сейчас, но что не так с

if (value == null) {
   // do whatever you want;
} else if (value instanceof Bundle) {
   out.append(bundleToString((Bundle) value));
} else if (value.getClass().isArray()) {
   out.append(Arrays.toString((Object[]) value));
} else {
   out.append(value);
}

КСТАТИ 1: NCSS и связанные параметры являются подсказками.Если у вас есть 20 разных случаев, у вас есть.В то время как вы всегда должны думать о слишком больших числах, иногда @SuppressWarning является правильным решением.

КСТАТИ 2: Каковы причины для создания статического bundleToString (Bundle) вместо переопределения Bundle.toString ()?

...