benf.org :  other :  cfr :  varargs

What's the difference between (A ... a) and (A[] a) ? Nothing. Unlike C++ where there needs to be stack manipulation by the caller (cdecl vs stdcall), varargs is just a method attribute. (This means it's impossible to tell the difference between the bytecode for the two calls to test2 below....)

It also means that, without the class file containing the method being called (only cut down information is present in the caller classfile), it's not possible to tell if a call site should be decompiled as varargs or not)

Note that here I'm using CFR with no varargs detection, and simply dumping the varargs attribute.

Original

    void test1(String a, String b, String c) {
        test2(a,b,c);
        test2(new String[]{a,b,c});
        test3(new String[]{a,b,c});
    }

    void test2(String ... a) {
        for (String x : a) {
            System.out.println(x);
        }
    }

    void test3(String [] a) {
        for (String x : a) {
            System.out.println(x);
        }
    }

CFR decompiled

void test1(String a, String b, String c)
{
    this.test2(new String[]{a, b, c});
    this.test2(new String[]{a, b, c});
    this.test3(new String[]{a, b, c});
    return;
}

varargs void test2(String[] a)
{
    for (String x : a) {
        System.out.println(x);
    }
    return;
}

void test3(String[] a)
{
    for (String x : a) {
        System.out.println(x);
    }
    return;
}

(FWIW, cfr 0.6 gets the method signature right, at least.. ;) )


Last updated 11/2012