java数据赋值的多种情况细节解读

java数据赋值时,不同的形式不同的赋值细节

    public static void testArrayAssign() {
        String[] args = {"hello", "world", "hhh"};
        Object[] objs0 = args;
        Object objs1[] = args;
        Object objs2[] = {args};
        Object[] objs3 = {args};
        System.out.println(args); // [Ljava.lang.String;@4554617c
        System.out.println(objs0); // [Ljava.lang.String;@4554617c
        System.out.println(objs1); // [Ljava.lang.String;@4554617c
        System.out.println(objs2); // [Ljava.lang.Object;@74a14482
        System.out.println(objs3); // [Ljava.lang.Object;@424c0bc4
    }

复制后的内存细节如下图:

java数据赋值的多种情况细节解读

可以看出 objs0 objs1 的赋值只是把args的引用赋给 objs0 objs1 并没有新建空间

而 objs2 objs3 这两种方式,则是把整个 args对象作为元素放到 objs2 objs3这两个数据里面,存的其实还是args的引用

 

objs2 objs3 这两种方式在反射中会用到,如

        String execClass = "reflect.TestClassLoader";
        String[] args = {"hello", "world", "hhh"};
        Object objs[] = {args};
        Object[] objs2 = args;
        CompileClassLoader ccl = new CompileClassLoader();
        Class<?> clazz = ccl.loadClass(execClass);
        Method main = clazz.getMethod("main", (new String[0]).getClass());
        main.invoke(null, objs);