とJVMのメソッド
1. 概要
JVMは、2つの異なるメソッドを使用して、オブジェクトインスタンスとクラスを初期化します。
このクイック記事では、コンパイラとランタイムがどのように
2. インスタンスの初期化メソッド
簡単なオブジェクトの割り当てと割り当てから始めましょう。
Object obj = new Object();
このスニペットをコンパイルし、 javap -c を介してそのバイトコードを見ると、次のようになります。
0: new #2 // class java/lang/Object
3: dup
4: invokespecial #1 // Method java/lang/Object."<init>":()V
7: astore_1
オブジェクトを初期化するには 、 JVMは、という名前の特別なメソッドを呼び出します
- クラスで定義されています
- その名前は < init>
- voidを返します
各クラスは0個以上のインスタンス初期化メソッドを持つことができます。 これらのメソッドは通常、JavaやKotlinなどのJVMベースのプログラミング言語のコンストラクターに対応しています。
2.1. コンストラクターとインスタンス初期化ブロック
Javaコンパイラがコンストラクタを次のように変換する方法をよりよく理解するため
public class Person {
private String firstName = "Foo"; // <init>
private String lastName = "Bar"; // <init>
// <init>
{
System.out.println("Initializing...");
}
// <init>
public Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// <init>
public Person() {
}
}
これは、このクラスのバイトコードです。
public Person(java.lang.String, java.lang.String);
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #7 // String Foo
7: putfield #9 // Field firstName:Ljava/lang/String;
10: aload_0
11: ldc #15 // String Bar
13: putfield #17 // Field lastName:Ljava/lang/String;
16: getstatic #20 // Field java/lang/System.out:Ljava/io/PrintStream;
19: ldc #26 // String Initializing...
21: invokevirtual #28 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
24: aload_0
25: aload_1
26: putfield #9 // Field firstName:Ljava/lang/String;
29: aload_0
30: aload_2
31: putfield #17 // Field lastName:Ljava/lang/String;
34: return
- まず、firstNameおよびlastNameフィールドを初期化します(インデックス0から13)
- 次に、インスタンス初期化ブロック(インデックス16から21)の一部としてコンソールに何かを出力します。
- そして最後に、コンストラクター引数でインスタンス変数を更新します
次のようにPersonを作成する場合:
Person person = new Person("Brian", "Goetz");
次に、これは次のバイトコードに変換されます。
0: new #7 // class Person
3: dup
4: ldc #9 // String Brian
6: ldc #11 // String Goetz
8: invokespecial #13 // Method Person."<init>":(Ljava/lang/String;Ljava/lang/String;)V
11: astore_1
今回、JVMは別の
ここで重要なポイントは、コンストラクターと他のインスタンス初期化子が
3. クラス初期化メソッド
Javaでは、静的初期化ブロックは、クラスレベルで何かを初期化する場合に役立ちます。
public class Person {
private static final Logger LOGGER = LoggerFactory.getLogger(Person.class); // <clinit>
// <clinit>
static {
System.out.println("Static Initializing...");
}
// omitted
}
上記のコードをコンパイルすると、コンパイラは静的ブロックをバイトコードレベルでクラス初期化メソッドに変換します。
簡単に言うと、メソッドは、次の場合にのみクラスの初期化になります。
- その名前は
- voidを返します
したがって、を生成する唯一の方法は
JVMは
4. 結論
この簡単な記事では、
JVMで初期化がどのように機能するかをよりよく理解するには、JVM仕様を読むことを強くお勧めします。