Java “makeConcat;”方法如何实现以及通过直接调用API使用的“StringConcatFactory”中的“makeConcatWithConstants”?
我相信自从Java “makeConcat;”方法如何实现以及通过直接调用API使用的“StringConcatFactory”中的“makeConcatWithConstants”?,java,string,dynamic,string-concatenation,invokedynamic,Java,String,Dynamic,String Concatenation,Invokedynamic,我相信自从java9以来,字符串连接已经使用StringConcatFactory实现 既然这是作为Java中的API提供的,那么方法makeConcat是如何实现的和makeConcatWithConstants?到目前为止,我还没有找到任何不同使用方法的例子。另外,makeConcat中的String name,MethodType-concatType参数是什么和makeConcatWithConstants和参数String recipe,对象。。。常量在MakeContatWith
java9
以来,字符串连接已经使用StringConcatFactory
实现
既然这是作为Java中的API提供的,那么方法
makeConcat是如何实现的在StringConcatFactory
中通过直接调用API使用code>和makeConcatWithConstants
?到目前为止,我还没有找到任何不同使用方法的例子。另外,makeConcat中的String name
,MethodType-concatType
参数是什么代码>和makeConcatWithConstants
和参数String recipe
,对象。。。常量
在MakeContatWithConstants中
的意思和应该传递给它们的内容对我来说不是不言而喻的。您链接的文档中指出,“这些方法通常用作引导方法…以支持字符串连接功能”,这意味着,编译器使用它们来准备进行字符串连接——换句话说,程序员不打算使用它们(正如我所记得的,它们基本上创建了一种(lambda)方法来进行连接)
使用它的简单方法是:使用+
操作符连接字符串,并让编译器完成这项工作。如果您真的想直接使用这些方法(为什么?这并不是那么简单),请使用连接创建一个类,并使用反编译器检查生成的Java代码
另请参见:(不是100%相关,而是最后一句)您不应该直接调用此API。该类被设计为为为invokedynamic
指令提供引导方法,因此其API直接用于该用例,而不是直接调用
但它是详尽的:
参数
lookup
-表示具有调用者访问权限的查找上下文。与invokedynamic
一起使用时,虚拟机会自动将其堆叠起来
name
-要实现的方法的名称此名称是任意的,对于此链接方法没有任何意义。与invokedynamic
一起使用时,这由invokedynamic
结构的名称和类型提供,并由VM自动堆叠
concatType
-呼叫站点的预期签名参数类型表示串联参数的类型;返回类型始终可从分配。与invokedynamic
一起使用时,这由invokedynamic
结构的名称和类型提供,并由VM自动堆叠
我补充的重点
请注意,JVM通常是如何根据invokedynamic
字节码指令自动提供所有参数的。在此上下文中,它是一条指令,使用一些参数并生成一个字符串
,将此引导方法称为知道如何执行操作的实体
无论出于何种原因,当您想要手动调用它时,您必须执行以下操作
String arg1=“你好”;
字符arg2='';
字符串arg3=“StringConcatFactory”;
MethodHandle mh=StringConcatFactory.makeConcat(
MethodHandles.lookup(),//通常由JVM提供
“foobar”,//通常由javac提供,但在这里没有意义
//方法类型通常由JVM提供,并与调用匹配
MethodType.MethodType(String.class、String.class、char.class、String.class))
.getTarget();
//我们现在可以使用句柄来执行连接
//参数类型必须与上面指定的MethodType匹配
字符串结果=(字符串)mh.invokeExact(arg1、arg2、arg3);
系统输出打印项次(结果);
您可以对多个字符串串联重复使用MethodHandle
,但您的字符串绑定到引导过程中指定的参数类型
对于普通字符串连接表达式,每个表达式在引导期间都会链接到一个句柄,该句柄与固定数量的子表达式及其编译时类型相匹配
很难想象直接使用API比编写arg1+arg2+arg3
等更有好处的场景
bootstrap方法允许指定除可能更改的参数之外的常量部分。例如,当我们有了代码
String time=switch(LocalTime.now().get(ChronoField.HOUR/u-OF-DAY)/6){
案例0->“晚上”;案例1->“上午”;案例2->“下午”;
案例3->“晚间”;默认->抛出新断言错误();
};
System.out.println(“Hello”+System.getProperty(“user.name”)+”,good“+time+”!”;
我们有几个常量部分,编译器可以将这些常量部分合并为一个字符串,使用占位符\1
表示必须插入动态值的位置,因此recipe
参数将是“Hello\1,good\1!”
。另一个参数,常量
,将不使用。然后,相应的invokedynamic
指令只需要在操作数堆栈上提供两个动态值
为了使等效的手动调用更有趣,我们假设系统属性user.name
是不变的,因此我们可以在引导调用中将其作为常量提供,使用占位符\2
引用它,并生成一个只使用一个动态参数的句柄,时间字符串:
MethodHandle mh=StringConcatFactory.makeConcatWithConstants(
MethodHandles.lookup(),//通常由JVM提供
“foobar”,//通常由javac提供,但在这里没有意义
//方法类型通常由JVM提供,并与调用匹配
MethodType.MethodType(S)