Created
December 8, 2020 11:58
-
-
Save sirinath/a8facf06ccaabb481efc0d27994d9f81 to your computer and use it in GitHub Desktop.
StringConcatFactory Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//https://stackoverflow.com/questions/65139541 | |
import java.lang.invoke.MethodHandle; | |
import java.lang.invoke.MethodHandles; | |
import java.lang.invoke.MethodType; | |
import java.lang.invoke.StringConcatException; | |
import java.lang.invoke.StringConcatFactory; | |
import java.time.LocalTime; | |
import java.time.temporal.ChronoField; | |
import java.util.spi.ToolProvider; | |
public class Main { | |
public static void main(String[] args) throws Throwable { | |
String time = switch(LocalTime.now().get(ChronoField.HOUR_OF_DAY) / 6) { | |
case 0 -> "night"; case 1 -> "morning"; case 2 -> "afternoon"; | |
case 3 -> "evening"; default -> throw new AssertionError(); | |
}; | |
System.out.println("Hello "+System.getProperty("user.name")+", good "+time+"!"); | |
String tmp = "prefix \1 "+time+" \2 suffix"; | |
invokeManually(time); | |
showBytecode(); | |
} | |
private static void invokeManually(String time) throws Throwable { | |
MethodHandle mh = StringConcatFactory.makeConcatWithConstants( | |
MethodHandles.lookup(), // normally provided by the JVM | |
"foobar", // normally provided by javac, but meaningless here | |
// method type is normally provided by the JVM and matches the invocation | |
MethodType.methodType(String.class, String.class), | |
"Hello \2, good \1!", // recipe, \1 binds a parameter, \2 a constant | |
System.getProperty("user.name") // the first constant to bind | |
).getTarget(); | |
// we can now use the handle to perform a concatenation | |
// the argument types must match the MethodType specified above | |
String result = (String)mh.invokeExact(time); | |
System.out.println(result); | |
} | |
private static void showBytecode() { | |
System.out.println(); | |
ToolProvider.findFirst("javap") | |
.ifPresent(tp -> tp.run(System.out, System.err, "-v", "-c", Main.class.getName())); | |
} | |
private Main() {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment