| benf.org : other : cfr : Java 9 String concatenation |
As of Java 9, string concatenation is no longer performed with StringBuilder, as previously. Java 9 introduced the StringConcatFactory, as described in JEP280. Another nice writeup is here.
CFR 133 will handle StringConcatFactory::makeConcat (javac with -XDstringConcat=indy), and StringConcatFactory::makeConcatWithConstants (-XDstringConcat=indyWithConstants - the default)
This mostly behaves entirely as expected, however there are a few things that are quite interesting points (from a decompilation point of view - as always, nothing in here is new or exciting!)
Consider
public static void main(String [] args) {
byte b1 = (byte)254;
System.out.println("foo " + b1 + ((byte)254>(byte)1));
}
This will get constant folded to "foo" + b1 + false, so in java 8, we'd get
System.out.println("foo " + b1 + false);
However, now the true is embedded in the string arguments - if we compile with java9+, then decompile with --stringconcat=false, we see
public static void main(String[] args) {
byte b1 = -2;
System.out.println((String)((Object)StringConcatFactory.makeConcatWithConstants(new Object[]{"foo \u0001false"}, (byte)b1)));
}
Which means CFR will reconstruct as (decompiling without any overrides)
public static void main(String[] args) {
byte b1 = -2;
System.out.println("foo " + b1 + "false");
}
public void test(int y) {
int x = y+2;
int z = x;
int a = z+1;
if (a > 3) z = 2;
System.out.print("" + a + x + "" + z);
}
Becomes (when decompiled with --stringconcat=false)
public void test(int y) {
int x = y + 2;
int z = x;
int a = z + 1;
if (a > 3) {
z = 2;
}
System.out.print((String)((Object)StringConcatFactory.makeConcatWithConstants(new Object[]{"\u0001\u0001\u0001"}, (int)a, (int)x, (int)z)));
}
As such, it's not really possible to infer missing empty strings! Similarly, addition of a single character can't be distinguished from a string.
| Last updated 09/2018 |