简体   繁体   中英

Java get class of array type

Is there a difference, and if yes, then what is the difference between new String[0].getClass() and String[].class ?

I am interested in facts like (non-exhaustive list):

  • do both initialise an empty array?
  • is this empty array cached in the JVM?
  • do they operate on the some array-class-object?
  • are they the same on the byte-code level?

Note: Probably it is somehow written in the JLS, but I couldn't find a proper description anywhere.

The expression new String[0].getClass() gets straight-forwardly compiled to instructions to create a new array, followed by a method invocation of getClass() . In contrast, the class literal String[].class gets compiled to a single ldc instruction, as elaborated in “How is a class literal compiled to Java bytecode?” .

You can verify this by running the following program

package jvm;

import javax.tools.ToolProvider;

public class GetArrayClass {
    public static Class<?> viaGetClass() {
        return new String[0].getClass();
    }
    public static Class<?> viaClassLiteral() {
        return String[].class;
    }
    public static void main(String[] args) {
        decompile();
    }
    private static void decompile() {
        Object args = new String[]{"-c", GetArrayClass.class.getName()};
        try {
            ToolProvider.getSystemJavaCompiler().getClass().getClassLoader()
                .loadClass("com.sun.tools.javap.Main")
                .getMethod("main", String[].class).invoke(null, args);
        } catch(ReflectiveOperationException ex) {
            throw new IllegalStateException(ex);
        }
    }
    private GetArrayClass(){}
}

Demo on Ideone

public static java.lang.Class<?> viaGetClass();
    Code:
       0: iconst_0
       1: anewarray     #1                  // class java/lang/String
       4: invokevirtual #2                  // Method java/lang/Object.getClass:()Ljava/lang/Class;
       7: areturn

public static java.lang.Class<?> viaClassLiteral();
    Code:
       0: ldc           #3                  // class "[Ljava/lang/String;"
       2: areturn

The expression new String[0] can not get replaced by a shared array, as the new operator is guaranteed to produce a new object with a distinct identity, ie new String[0] != new String[0] . But in a use case like this, where the instance is temporary and no identity sensitive operations are performed, chances are high that the JVM's optimizer will eliminate the allocation, in case it becomes a hot spot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM