局部函数
所谓局部函数就是在函数内部定义函数
关于java
java显然在语法上是不支持的. 这样的代码显然是会报错的.
public class Test {
public static void main(String[] args) {
public void doSome () {
System.out.println("This is a local method");
}
doSome();
}
}
关于Kotlin
kotlin显然是支持这样的写法的.
fun main() {
fun localFunction() {
println("I am local function")
}
localFunction()
}
实现原理
秉承着知其然知其所以然,很有必要知道这样一个方便的语法特性是如何是如何实现的. 打开show kotlin bytecode插件decompile ohh~ 好像看不懂
public final class LocalFunctionKt {
public static final void main() {
<undefinedtype > $fun$localFunction$1 = null.INSTANCE;
$fun$localFunction$1.invoke();
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
考虑看看有咩有额外的的class生成, 经分析后发现显然没有
接着分析字节码
{
public static final void main();
descriptor: ()V
flags: (0x0019) ACC_PUBLIC, ACC_STATIC, ACC_FINAL
Code:
stack=0, locals=0, args_size=0
0: invokestatic #9 // Method main$localFunction:()V
3: return
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: (0x1009) ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC
Code:
stack=0, locals=1, args_size=1
0: invokestatic #12 // Method main:()V
3: return
LocalVariableTable:
Start Length Slot Name Signature
0 4 0 args [Ljava/lang/String;
private static final void main$localFunction();
descriptor: ()V
flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL
Code:
stack=2, locals=0, args_size=0
0: ldc #16 // String I am local function
2: getstatic #22 // Field java/lang/System.out:Ljava/io/PrintStream;
5: swap
6: invokevirtual #28 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
9: return
LineNumberTable:
line 3: 0
line 4: 9
}
代码等价于
public final class LocalFunctionKt {
public static final void main() {
main$localFunction();
}
public static void main(String[] args) {
main();
}
private static final void main$localFunction() {
System.out.println("I am local function");
}
}
- 所以kotlin的局部函数其实也就是普通的函数
- 编译以后是同级的
- 其实现原理也就是通过编译器静态检查从而实现所谓的局部