Элементы массива Java Access из массива объектов, содержащего объект, содержащий двойной массив в Intellij - PullRequest
0 голосов
/ 07 февраля 2019

Предыстория: у меня есть приложение с пружинной загрузкой, которое получает входные параметры любого метода, помеченного пользовательской аннотацией.Он помещает типы этих параметров в массив классов 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 расширяет Object.

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

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

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

Edit: Весенний загрузочный класс, который обеспечивает clazz (т.е. классы) и obj (то есть params)

@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;
    }
}

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

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Нашел решение для своего поста.Для дальнейшего использования выясняется, что существует зависимость от 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;
}
0 голосов
/ 07 февраля 2019

Если я правильно понимаю, вы можете использовать класс-обёртку и напечатать его 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), потому что они будутне быть массивом объектов.

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