Skip to content

Instantly share code, notes, and snippets.

@knjname
Last active December 17, 2015 07:59
Show Gist options
  • Save knjname/5576823 to your computer and use it in GitHub Desktop.
Save knjname/5576823 to your computer and use it in GitHub Desktop.
Java8の実質final扱いの動作について
(おまけ)
Classfile /C:/Users/owner/IdeaProjects/untitled/src/LambdasVirtualFinal.class
Last modified 2013/05/15; size 1277 bytes
MD5 checksum 0b392ccf6e250072a853f421a45b92a2
Compiled from "LambdasVirtualFinal.java"
public class LambdasVirtualFinal
SourceFile: "LambdasVirtualFinal.java"
InnerClasses:
static #5; //class LambdasVirtualFinal$1
public static final #65= #64 of #69; //Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles
BootstrapMethods:
0: #27 invokestatic java/lang/invoke/LambdaMetafactory.metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
Method arguments:
#28 invokeinterface java/util/function/IntConsumer.accept:(I)V
#29 invokestatic LambdasVirtualFinal.lambda$0:(II)V
#30 (I)V
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #10.#23 // java/lang/Object."<init>":()V
#2 = InterfaceMethodref #24.#25 // java/util/stream/IntStream.range:(II)Ljava/util/stream/IntStream;
#3 = InvokeDynamic #0:#31 // #0:lambda$:(I)Ljava/util/function/IntConsumer;
#4 = InterfaceMethodref #24.#32 // java/util/stream/IntStream.forEach:(Ljava/util/function/IntConsumer;)V
#5 = Class #33 // LambdasVirtualFinal$1
#6 = Methodref #5.#34 // LambdasVirtualFinal$1."<init>":(II)V
#7 = Fieldref #35.#36 // java/lang/System.out:Ljava/io/PrintStream;
#8 = Methodref #37.#38 // java/io/PrintStream.println:(I)V
#9 = Class #39 // LambdasVirtualFinal
#10 = Class #40 // java/lang/Object
#11 = Utf8
#12 = Utf8 InnerClasses
#13 = Utf8 <init>
#14 = Utf8 ()V
#15 = Utf8 Code
#16 = Utf8 LineNumberTable
#17 = Utf8 main
#18 = Utf8 ([Ljava/lang/String;)V
#19 = Utf8 lambda$0
#20 = Utf8 (II)V
#21 = Utf8 SourceFile
#22 = Utf8 LambdasVirtualFinal.java
#23 = NameAndType #13:#14 // "<init>":()V
#24 = Class #41 // java/util/stream/IntStream
#25 = NameAndType #42:#43 // range:(II)Ljava/util/stream/IntStream;
#26 = Utf8 BootstrapMethods
#27 = MethodHandle #6:#44 // invokestatic java/lang/invoke/LambdaMetafactory.metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
#28 = MethodHandle #9:#45 // invokeinterface java/util/function/IntConsumer.accept:(I)V
#29 = MethodHandle #6:#46 // invokestatic LambdasVirtualFinal.lambda$0:(II)V
#30 = MethodType #47 // (I)V
#31 = NameAndType #48:#49 // lambda$:(I)Ljava/util/function/IntConsumer;
#32 = NameAndType #50:#51 // forEach:(Ljava/util/function/IntConsumer;)V
#33 = Utf8 LambdasVirtualFinal$1
#34 = NameAndType #13:#20 // "<init>":(II)V
#35 = Class #52 // java/lang/System
#36 = NameAndType #53:#54 // out:Ljava/io/PrintStream;
#37 = Class #55 // java/io/PrintStream
#38 = NameAndType #56:#47 // println:(I)V
#39 = Utf8 LambdasVirtualFinal
#40 = Utf8 java/lang/Object
#41 = Utf8 java/util/stream/IntStream
#42 = Utf8 range
#43 = Utf8 (II)Ljava/util/stream/IntStream;
#44 = Methodref #57.#58 // java/lang/invoke/LambdaMetafactory.metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
#45 = InterfaceMethodref #59.#60 // java/util/function/IntConsumer.accept:(I)V
#46 = Methodref #9.#61 // LambdasVirtualFinal.lambda$0:(II)V
#47 = Utf8 (I)V
#48 = Utf8 lambda$
#49 = Utf8 (I)Ljava/util/function/IntConsumer;
#50 = Utf8 forEach
#51 = Utf8 (Ljava/util/function/IntConsumer;)V
#52 = Utf8 java/lang/System
#53 = Utf8 out
#54 = Utf8 Ljava/io/PrintStream;
#55 = Utf8 java/io/PrintStream
#56 = Utf8 println
#57 = Class #62 // java/lang/invoke/LambdaMetafactory
#58 = NameAndType #63:#66 // metaFactory:(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
#59 = Class #67 // java/util/function/IntConsumer
#60 = NameAndType #68:#47 // accept:(I)V
#61 = NameAndType #19:#20 // lambda$0:(II)V
#62 = Utf8 java/lang/invoke/LambdaMetafactory
#63 = Utf8 metaFactory
#64 = Class #70 // java/lang/invoke/MethodHandles$Lookup
#65 = Utf8 Lookup
#66 = Utf8 (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
#67 = Utf8 java/util/function/IntConsumer
#68 = Utf8 accept
#69 = Class #71 // java/lang/invoke/MethodHandles
#70 = Utf8 java/lang/invoke/MethodHandles$Lookup
#71 = Utf8 java/lang/invoke/MethodHandles
{
public LambdasVirtualFinal();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
public static void main(java.lang.String...);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC, ACC_VARARGS
Code:
stack=4, locals=3, args_size=1
0: iconst_0
1: istore_1
2: iconst_0
3: bipush 100
5: invokestatic #2 // InterfaceMethod java/util/stream/IntStream.range:(II)Ljava/util/stream/IntStream;
8: iload_1
9: invokedynamic #3, 0 // InvokeDynamic #0:lambda$:(I)Ljava/util/function/IntConsumer;
14: invokeinterface #4, 2 // InterfaceMethod java/util/stream/IntStream.forEach:(Ljava/util/function/IntConsumer;)V
19: iconst_0
20: istore_2
21: new #5 // class LambdasVirtualFinal$1
24: dup
25: iload_1
26: iload_2
27: invokespecial #6 // Method LambdasVirtualFinal$1."<init>":(II)V
30: pop
31: return
LineNumberTable:
line 10: 0
line 13: 2
line 22: 19
line 24: 21
line 32: 31
}
Classfile /C:/Users/owner/IdeaProjects/untitled/src/LambdasVirtualFinal$1.class
Last modified 2013/05/15; size 634 bytes
MD5 checksum f2dd39b0ad135530cb34ae8bf4509ce4
Compiled from "LambdasVirtualFinal.java"
final class LambdasVirtualFinal$1 implements java.lang.Runnable
SourceFile: "LambdasVirtualFinal.java"
EnclosingMethod: #21.#22 // LambdasVirtualFinal.main
InnerClasses:
static #6; //class LambdasVirtualFinal$1
minor version: 0
major version: 52
flags: ACC_FINAL, ACC_SUPER
Constant pool:
#1 = Fieldref #6.#23 // LambdasVirtualFinal$1.val$outer:I
#2 = Fieldref #6.#24 // LambdasVirtualFinal$1.val$outer2:I
#3 = Methodref #7.#25 // java/lang/Object."<init>":()V
#4 = Fieldref #26.#27 // java/lang/System.out:Ljava/io/PrintStream;
#5 = Methodref #28.#29 // java/io/PrintStream.println:(I)V
#6 = Class #30 // LambdasVirtualFinal$1
#7 = Class #33 // java/lang/Object
#8 = Class #34 // java/lang/Runnable
#9 = Utf8 val$outer
#10 = Utf8 I
#11 = Utf8 val$outer2
#12 = Utf8 <init>
#13 = Utf8 (II)V
#14 = Utf8 Code
#15 = Utf8 LineNumberTable
#16 = Utf8 run
#17 = Utf8 ()V
#18 = Utf8 SourceFile
#19 = Utf8 LambdasVirtualFinal.java
#20 = Utf8 EnclosingMethod
#21 = Class #35 // LambdasVirtualFinal
#22 = NameAndType #36:#37 // main:([Ljava/lang/String;)V
#23 = NameAndType #9:#10 // val$outer:I
#24 = NameAndType #11:#10 // val$outer2:I
#25 = NameAndType #12:#17 // "<init>":()V
#26 = Class #38 // java/lang/System
#27 = NameAndType #39:#40 // out:Ljava/io/PrintStream;
#28 = Class #41 // java/io/PrintStream
#29 = NameAndType #42:#43 // println:(I)V
#30 = Utf8 LambdasVirtualFinal$1
#31 = Utf8
#32 = Utf8 InnerClasses
#33 = Utf8 java/lang/Object
#34 = Utf8 java/lang/Runnable
#35 = Utf8 LambdasVirtualFinal
#36 = Utf8 main
#37 = Utf8 ([Ljava/lang/String;)V
#38 = Utf8 java/lang/System
#39 = Utf8 out
#40 = Utf8 Ljava/io/PrintStream;
#41 = Utf8 java/io/PrintStream
#42 = Utf8 println
#43 = Utf8 (I)V
{
final int val$outer;
descriptor: I
flags: ACC_FINAL, ACC_SYNTHETIC
final int val$outer2;
descriptor: I
flags: ACC_FINAL, ACC_SYNTHETIC
LambdasVirtualFinal$1(int, int);
descriptor: (II)V
flags:
Code:
stack=2, locals=3, args_size=3
0: aload_0
1: iload_1
2: putfield #1 // Field val$outer:I
5: aload_0
6: iload_2
7: putfield #2 // Field val$outer2:I
10: aload_0
11: invokespecial #3 // Method java/lang/Object."<init>":()V
14: return
LineNumberTable:
line 24: 0
public void run();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_0
4: getfield #1 // Field val$outer:I
7: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
10: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream;
13: aload_0
14: getfield #2 // Field val$outer2:I
17: invokevirtual #5 // Method java/io/PrintStream.println:(I)V
20: return
LineNumberTable:
line 26: 0
line 27: 10
line 29: 20
}
import java.util.stream.IntStream;
public class LambdasVirtualFinal {
public static void main(String... args){
int outer = 0;
// 外部の変数の参照はできる.
IntStream.range(0, 100).forEach(i -> System.out.println(i + outer));
// しかしlambda内で参照されている外の変数outerは実質finalとして扱われる.
// なので、lambda内部で更新できない
// IntStream.range(0, 100).forEach( i -> outer += i);
// 一度lambda内部で使用されたりすると, final宣言がついたように扱われるので、外でも更新できない.
// outer = 999999;
int outer2 = 0;
// 匿名クラスでもローカル変数へのアクセスはlambdaと同様の扱いとなる
new Runnable(){
public void run(){
System.out.println(outer2); // これもlambda同様、実質final扱い。
// outer2++; 当然更新不可。
}
};
// outer2++; 実質final扱いされているので、更新できない。
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment