为什么 kotlin
的方法名中可以有空格等特殊字符?
在 Coding conventions 一文的 Names for test methods 部分,有如下的内容

大意是说我们在测试类中可以定义有特殊名称的方法,例如方法名可以是 ensure everything works
(由于名称中有空格,所以需要把它写在一对 ````` 字符中)。 但是在 java
中,并不支持这样的语法,那么作为同样运行在 JVM
上的语言,kotlin
是如何做到这一点的呢?
我自己试了试,kotlin
中的普通类中,也可以定义名称中有特殊字符的方法(方法名要写在一对 ````` 字符中)。
结论
Java Virtual Machine Specification 中对方法名的限制比较宽松,空格(即
)等特殊字符允许出现在方法名中,所以 kotlin
并没有违反 Java Virtual Machine Specification。
代码
名称中含有特殊字符的方法
我们用如下的 kotlin
代码来进行验证。(请将其保存为 C.kt
)
kotlin
class C {
fun `hello world function with a special name`(): Unit {
println("Hello world")
}
}
kotlinc C.kt
命令可以编译 C.kt
。编译后,会生成 C.class
。 我们用 javap -v -p C
来查看 C.class
的内容。 和 hello world function with a special name
方法有关的部分如下 ⬇️
text
public final void hello world function with a special name();
descriptor: ()V
flags: (0x0011) ACC_PUBLIC, ACC_FINAL
Code:
stack=2, locals=1, args_size=1
0: ldc #13 // String Hello world
2: getstatic #19 // Field java/lang/System.out:Ljava/io/PrintStream;
5: swap
6: invokevirtual #25 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
9: return
LineNumberTable:
line 3: 0
line 4: 9
LocalVariableTable:
Start Length Slot Name Signature
0 10 0 this LC;
利用 javap
命令给出的结果,可以手动写出对应的 java 代码如下 ⬇️
java
// 以下内容是我手动转化出来的,不保证绝对准确,仅供参考
// C 类上有注解,这里略去
public final class C {
public C() {
super();
}
// 注意:实际上 java 不允许在方法名里使用空格,这里只是参考 kotlin 展示一下方法名,请读者不要误会
public final void `hello world function with a special name`() {
System.out.println("Hello world");
}
}
看来在 class
文件中,那个方法的名字也是 hello world function with a special name
,我们写点 java
代码来验证一下。
用 java
代码来调用它
请将如下代码保存为 Main.java
java
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
C c = new C();
for (Method method : C.class.getDeclaredMethods()) {
System.out.println("method name is: [" + method.getName() + "]");
method.invoke(c);
}
}
}
如下的两个命令可以编译 Main.java
并运行其中的 main(...)
方法。
bash
javac -g -parameters Main.java
java Main
运行结果如下,可见我们的推测是正确的,class
文件中的文件名也是 hello world function with a special name
。

解释
根据我们日常写 java
的经验可知,java
代码中是不允许方法名中出现空格等特殊字符的,那么为什么 kotlin
的代码里就允许呢? 我在Java Virtual Machine Specification 的 4.2.2. Unqualified Names 找到了这样的描述

其中对方法名的限制是
- 方法名中至少要含有一个
Unicode
字符,且方法名中不允许 出现.
;
[
/
这4个字符 - 除了
<init>
和<clinit>
这两个特殊的方法名外,方法名中不允许 出现<
>
这两个字符
这么说来,在 kotlin
中,方法名也仍旧是有限制的,比如方法名中应该不可以出现 .
这个字符。 如果我们把 C.kt
改成如下的内容,那么会发现,编译失败了
kotlin
class C {
fun `hello . world function with a special name`(): Unit {
println("Hello world")
}
}
