2

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.

Lake_Lagunita
  • 521
  • 1
  • 4
  • 20
  • Using `"".value` simply causes the string to be an empty character sequence rather than an undefined value which could cause all manner of issues. – sorifiend Aug 04 '21 at 03:36
  • 2
    The definition of `"".value` is "the `value` field of the empty string". How is this circular? Note that `this` is not the same object as `""`. – Sweeper Aug 04 '21 at 03:37
  • @sorifiend exactly what issues are thinking about? because I find this constructor really dumb – Eugene Aug 04 '21 at 03:37
  • the only use case of this is when you would want to define a new empty String, not being a literal. When _exactly_ that would make any sense is beyond me – Eugene Aug 04 '21 at 03:39
  • @sorifiend Do you mean that when computer compiles the code "".value, it will detect that ""means an empty string so it will create an empty string object and initialize its value as a char[0] (new char[]{}) – Lake_Lagunita Aug 04 '21 at 03:43
  • @Sweeper it's not circular. what I mean is that how does Java know that "" means empty string and also I didn't find the definition of empty string constructor. – Lake_Lagunita Aug 04 '21 at 03:46
  • `String` doesn't have just this one constructor, does it? The object representing the empty string can be created using a constructor other than the one that you've shown here, right? I haven't looked into which one it is exactly though. – Sweeper Aug 04 '21 at 03:52
  • @Sweeper yes. what I really need to make clear is : for empty string "", what is its constructor. However, I can't put a break point to see how this happens. – Lake_Lagunita Aug 04 '21 at 04:10

1 Answers1

4

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

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
  • 1+, already constructed is the key here. Now, why in the world such a thing is needed? do you happen to know? – Eugene Aug 04 '21 at 03:48
  • 2
    @Eugene: like you I think it makes no sense. They must’ve wanted String to have a zero arg constructor for something but who knows what. – Nathan Hughes Aug 04 '21 at 03:49
  • So actually the compiler can detect that "" represents empty string? Then for empty string, what is the corresponding constructor? using public String(char value[]) ? – Lake_Lagunita Aug 04 '21 at 03:55
  • @LeonloveKaren: I don’t see that the spec tells what constructor to use. It would definitely not use the no arg one. – Nathan Hughes Aug 04 '21 at 04:02
  • To sum up, what I really need to make clear is : for empty string "", what is its constructor. However, I can't put a break point to see how this happens. – Lake_Lagunita Aug 04 '21 at 04:08
  • That would be an implementation detail up to the jvm. – Nathan Hughes Aug 04 '21 at 04:13
  • Well, it's going to be an empty array of characters. And this code is just reusing one that's already in the string pool. – Dawood ibn Kareem Aug 04 '21 at 04:59