来自对象数组的Java Access数组元素,该对象数组包含在Intellij中包含双精度数组的对象

时间:2019-02-07 19:59:28

标签: java spring maven spring-boot intellij-idea

背景故事:我有一个Spring Boot应用程序,该应用程序获取使用自定义注释注释的任何方法的输入参数。它将那些参数的类型放在类数组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数组时,由于Double扩展Object,所以无法将其强制转换回Object数组。

选项2:这次由于语法错误,代码甚至无法编译:Arrays.deepToString需要一个Object数组,但是在运行时之前,语法检查器只能看到Object。直到运行时之后,包装在对象中的Double []才沿着堆栈发送。

这对于其他数据结构(例如Hashmap,ArrayList)也是一个问题。

是否有某种方法可以获取对象o的元素?我无法控制哪些原始类型或对象是带注释方法的输入,因此不能更改clazz和obj。

编辑:提供了clazz(即类)和obj(即params)的Spring Boot类

@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依赖项中找到了解决方案,并将其发布在这里。

2 个答案:

答案 0 :(得分:0)

如果我理解正确,则可以使用包装器类并将其打印为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)中。

答案 1 :(得分:0)

找到了我自己帖子的解决方案。供以后参考,事实证明有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;
}