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