A question about initializing a newly created empty string in Java

Viewed 146

I am reading the source code of String.java in OpenJDK jdk16u.

One of its constructors is shown as follows:

    /**
     * Initializes a newly created {@code String} object so that it represents
     * an empty character sequence.  Note that use of this constructor is
     * unnecessary since Strings are immutable.
     */
    public String() {
        this.value = "".value;
        this.coder = "".coder;
    }

Apparently that .value refers to this private byte array:

    /**
     * The value is used for character storage.
     *
     * @implNote This field is trusted by the VM, and is a subject to
     * constant folding if String instance is constant. Overwriting this
     * field after construction will cause problems.
     *
     * Additionally, it is marked with {@link Stable} to trust the contents
     * of the array. No other facility in JDK provides this functionality (yet).
     * {@link Stable} is safe here, because value is never null.
     */
    @Stable
    private final byte[] value;

This means that when we use String() as a constructor, this.value references "".value. However, I can't find the exact definition of "".value. It seems to me like a circular definition.

Edit: it's not circular definition. what I mean is that how does Java know that "" means empty string.

1 Answers

this is the object being constructed. the empty string represented by the literal “” is an already existing string object, which is separate from the object being constructed. value is a private field on String. The code assigns the pre-existing empty string value to the new object’s value. There is no circularity here.

It is a bit weird that an object can see another object’s private members, this is allowed inside a class definition as long as the other object has the same type. Usually you see this in equals methods.

Literal syntax for String is coded into the compiler. Different JVM languages allow different literal syntaxes for different kinds of objects, the syntax is part of the language. Groovy, Clojure, and Scala all have very different literal syntaxes for various things. Rules for literals are spelled out in https://docs.oracle.com/javase/specs/jls/se16/html/jls-3.html#jls-3.10.5

Related