I compiled this code. (use javac 21.0.1)
public static final String MAX = "AAAAA ...";
If I repeat 'A' 65534 times in a literal, the compilation is OK.
But if I repeat 'A' 65535 times in a literal, I get a compile error 'constant string too long'.
Why is the length limit 65534 instead of 65535?
Specification
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
length: The value of the length item gives the number of bytes in the bytes array (not the length of the resulting string).
The maximum length of u2 is 0xFFFF = 65535, not 65534.
In UTF-8, "A" is 1 byte, so isn't the string length limited to 65535?
Javac source code
jdk/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java · openjdk/jdk
private void checkStringConstant(DiagnosticPosition pos, Object constValue) {
if (nerrs != 0 || // only complain about a long string once
constValue == null ||
!(constValue instanceof String str) ||
str.length() < PoolWriter.MAX_STRING_LENGTH)
return;
log.error(pos, Errors.LimitString);
nerrs++;
}
Is the correct code str.length() <= PoolWriter.MAX_STRING_LENGTH ?
The comparison has been in there since at least 2007. So it may be a bug that no one reported because no one used a string literal that big. I'm guessing the question is just about curiosity because I don't think anyone really needs that extra byte.