Java调用带美元符号的Kotlin生成方法为何编译失败?
为何Kotlin生成的
groupBy$default方法无法从Java调用 我在使用Kotlin DataFrame库时,尝试从Java代码调用其方法,通过javap命令查看字节码时能看到groupBy$default方法:
$ javap -cp . org/jetbrains/kotlinx/dataframe/api/GroupByKt.class Compiled from "groupBy.kt" public final class org.jetbrains.kotlinx.dataframe.api.GroupByKt { ... public static org.jetbrains.kotlinx.dataframe.api.GroupBy groupBy$default(org.jetbrains.kotlinx.dataframe.DataFrame, boolean, kotlin.jvm.functions.Function2, int, java.lang.Object); ...
反编译字节码也能看到该方法的调用逻辑,但在Eclipse和Maven中编译Java代码时,却报错找不到这个方法:
[ERROR] /prj/ks/KotlinxDataFrameTest.java:[130,21] cannot find symbol symbol: method groupBy$default(org.jetbrains.kotlinx.dataframe.DataFrame<capture#1 of ?>,boolean,(gb,it)->[...] ""),int,<nulltype>) location: class org.jetbrains.kotlinx.dataframe.api.GroupByKt
补充的javap -verbose输出显示该方法带有ACC_SYNTHETIC标记:
public static org.jetbrains.kotlinx.dataframe.api.GroupBy groupBy$default(org.jetbrains.kotlinx.dataframe.DataFrame, boolean, kotlin.jvm.functions.Function2, int, java.lang.Object); descriptor: (Lorg/jetbrains/kotlinx/dataframe/DataFrame;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lorg/jetbrains/kotlinx/dataframe/api/GroupBy; flags: (0x1009) ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC Code: stack=3, locals=5, args_size=5 0: iload_3 1: iconst_1 2: iand 3: ifeq 8 6: iconst_1 7: istore_1 8: aload_0 9: iload_1 10: aload_2 11: invokestatic #32 // Method groupBy:(Lorg/jetbrains/kotlinx/dataframe/DataFrame;ZLkotlin/jvm/functions/Function2;)Lorg/jetbrains/kotlinx/dataframe/api/GroupBy; 14: areturn StackMapTable: number_of_entries = 1 frame_type = 8 /* same */ LineNumberTable: line 21: 0
问题根源
你忽略了ACC_SYNTHETIC这个关键标记:
- 带这个标记的方法是Kotlin编译器自动生成的合成方法,并非源代码中显式定义的方法。这类方法是Kotlin内部用来实现语言特性(比如默认参数、重载解析)的,不对外提供稳定的调用接口。
- Java编译器会限制对合成方法的直接调用,即使
javap能看到它,也不意味着可以在Java代码中直接引用。 groupBy$default是Kotlin为处理groupBy方法的默认参数生成的辅助方法,仅用于Kotlin代码内部调用,其命名和签名可能随Kotlin版本变化,不保证兼容性。
解决方法
不要尝试调用$default后缀的合成方法,直接调用原始的groupBy方法,并手动传入所有参数(包括Kotlin中设置了默认值的参数):
- 查看Kotlin DataFrame库中
groupBy方法的原始签名,确认所有参数的默认值(比如那个boolean参数的默认值,可通过Kotlin源码或官方文档确认)。 - 在Java代码中调用
GroupByKt.groupBy(),传入所有必要的参数,替代对groupBy$default的调用。
内容的提问来源于stack exchange,提问作者levant pied
相关产品推荐
相关产品推荐

