Элементы массива Java Access из массива объектов, содержащего объект, содержащий двойной массив в Intellij

Предыстория: у меня есть приложение для весенней загрузки, которое получает входные параметры любого метода, аннотированного пользовательской аннотацией. Он помещает типы этих параметров в массив классов clazz, а значения — в массив объектов obj.

Это обобщено, поэтому элементы в obj могут быть массивами, например:

clazz = {int, java.lang.String, [D}
obj = {2, "Foobar", [3.1415, 2.718]}

Я пытаюсь распечатать все элементы в obj со следующим кодом. Обратите внимание, что clazz и obj всегда имеют одинаковую длину и одинаковые индексы связаны друг с другом (см. пример выше).

Код проверяет, является ли объект массивом, чтобы не печатать что-то вроде [D@431621

private void othermethod(Class[] clazz, Object[] obj){

    for(int i =0 ; i<clazz.length;i++){
        if (clazz[i].isArray()){
            System.out.println(ObjArrayDisplay(obj[i], clazz[i]));
        }
        else{
            System.out.println(obj[i].toString());
        }
    }
}

private String ObjArrayDisplay(Object o, Class c){
    //Option 1. return Arrays.deepToString((Object[])o);java.lang.ClassCastException: [D cannot be cast to [Ljava.lang.Object;
    //Option 2. return Arrays.deepToString(c.cast(o)); deepToString (java.lang.Object[]) in Arrays cannot be applied to (java.lang.Object)
}

И в этом заключается проблема.

Вернемся к примерам значений:

clazz = {int, java.lang.String, [D}
obj = {2, "Foobar", [3.1415, 2.718]}

Вариант 1: Для этого clazz и obj код компилируется, но когда код попадает в массив Double, его нельзя привести обратно к массиву Object, поскольку Double extends Object.

Вариант 2: на этот раз код даже не компилируется из-за синтаксической ошибки: Arrays.deepToString ожидает массив Object, но перед выполнением средство проверки синтаксиса видит только Object. Только после времени выполнения Double[], обернутый в объект, отправляется вниз по стеку.

Это также может быть проблемой с другими структурами данных, такими как Hashmap, ArrayList.

Есть ли способ получить элементы объекта o? У меня нет контроля над тем, какие примитивные типы или объекты являются входными данными для аннотированных методов, поэтому изменение clazz и obj не вариант.

Редактировать: Класс загрузки Spring, который предоставляет clazz (т.е. классы) и obj (т.е. параметры)

@Aspect
@Component
@Getter
public class Flow {
    @Autowired
    SubscriptionsIntegration SI;

    private Class[] classes;
    private Object[] params;
    private Object returnvalue = "Start";

    @Around("@annotation(TrackFlow)")
    public Object TrackFlow(ProceedingJoinPoint joinPoint) throws Throwable{

        CodeSignature cs = (CodeSignature) joinPoint.getSignature();

        classes = cs.getParameterTypes();
        params = joinPoint.getArgs();

        Object proceed = joinPoint.proceed();

        returnvalue = proceed;

        return proceed;
    }
}

Редактировать 2: Нашел решение в неясной зависимости maven и разместил его здесь.

Java — строго типизированный язык, поэтому делать что-то подобное всегда будет непросто. Чего именно вы пытаетесь достичь с помощью этих массивов clazz и object? Может быть, есть лучшая структура данных для их хранения?

ritratt 07.02.2019 21:08

Это вывод класса Spring Aspect с аннотацией @Around, который получает входные параметры из любого метода, аннотированного пользовательской аннотацией. Это рассматриваемый класс, который дает мне clazz и obj: Edit, теперь также добавлен в исходный пост.

P Lee 07.02.2019 21:16

AtAspect AtComponent AtGetter открытый класс Flow { @Autowired SubscriptionsIntegration SI; частные классы Class[]; частные параметры Object[]; частный объект returnvalue = "Старт"; @Around("@annotation(TrackFlow)") общедоступный объект TrackFlow(ProceedingJoinPoint joinPoint) throws Throwable{ CodeSignature cs = (CodeSignature) joinPoint.getSignature(); классы = cs.getParameterTypes(); params = joinPoint.getArgs(); Объект приступить = joinPoint.proceed(); возвращаемое значение = продолжить; возврат продолжить; } }

P Lee 07.02.2019 21:16
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
900
2

Ответы 2

Если я правильно понимаю, вы можете использовать класс-оболочку и напечатать его toString

class Scratch {
    public static void main(String[] args) {
        Double[] objects = {2.02,2.22,2.13};
        System.out.print(new Foo(objects));

        String[] strings = {"array","of", "strings"};
        System.out.print(new Foo(strings));

    }

    public static class Foo{
        private Object[] objects;
        public Foo(Object[] objects){
            this.objects=objects;
        }

        @Override
        public String toString() {
            return "Foo{" +
                    "objects = " + Arrays.toString(objects) +
                    '}';
        }
    }
}

Вы упомянули, что не можете контролировать, являются ли это примитивами, но они не будут переданы в private void othermethod(Class[] clazz, Object[] obj), потому что они не будут массивом объектов.

Массив объектов obj может содержать что угодно, от примитивов до массивов объектов. В моем исходном посте я упомянул, что элемент obj, который является двойным массивом, не может быть приведен обратно в массив объектов из-за наследования.

P Lee 07.02.2019 21:24

Я не уверен, что понимаю. Double[] не является Object[], но Double[] является Object[]. Int примитивен, а Integer нет. Итак, если у вас есть метод с параметром объектов Object[] и вы попытались передать в него double[] doubles, он не скомпилируется

J.D 07.02.2019 21:43

Да, вы технически правы насчет примитивов, хотя java преобразует примитивы, назначенные объектам, в их форму объекта, поэтому массив примитивов, приведенный к массиву объектов, функционально одинаков и будет компилироваться. В любом случае я нашел решение проблемы.

P Lee 07.02.2019 21:46

Нашел решение своего поста. Для справки в будущем, оказывается, есть зависимость Maven Jackson, которая может это сделать.

@Autowired
com.fasterxml.jackson.databind.ObjectMapper objectMapper;

//...other methods and variables

private String ObjArrayDisplay(Object o, Class c){
    String returnValue = null;
    try {
        returnValue = objectMapper.writeValueAsString(o);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }

    return returnValue;
}

Другие вопросы по теме