この質問を調査するには、リバースエンジニアリング「コンパイラは何をしますか?」を参照してください。 :)そのために
、我々は実行することにより、コンテンツ class C(x: Int){}
でクラスC.scala
をコンパイルされています
scalac C.scala
これは、C.class
を生成します。 コンパイラが生成する内容を確認するには、java class disassembler javapを使用できます。
javap -p C.class
を実行して生成します:
public class C {
public C(int);
}
を我々は class D(val x: Int){}
で全体の手順を繰り返している場合は、我々がもたらすであろう:
public class D {
private final int x;
public int x();
public D(int);
}
を我々は差がキーワードということであることがわかりますval
は、ゲッターメソッドを作成するようにクラスに指示しています。
val
キーワードがなければ、クラス変数は可変であると定義されます。これは間違っています。私たちが分解を深く理解できることを証明するために。実行することにより:
{
public C(int);
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=1, locals=2, args_size=2
0: aload_0
1: invokespecial #14 // Method java/lang/Object."<init>":()V
4: return
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LC;
0 5 1 x I
LineNumberTable:
line 4: 0
line 2: 4
MethodParameters:
Name Flags
x final
}
あなたは変数x
クラスはまだfinal
として宣言ので、不変であることをはっきりと見ることができます。
javap -p -v C.class
を我々は(他の多くの情報の中で)このスニペットを取得します。
最初の段落の3つの主張はすべて間違っています: 'val'と' var'は必ずしもpublicではなく、単にデフォルトです。修飾子を使用しない場合は、フィールドがある場合とない場合があります(パラメータがどのメソッドでも使用されているかどうかによって異なります)。 –
私は彼らがいつも公開されているわけではないことに同意します。 'private'を修正して使うこともできますが、答えのポイントはまだ残っていると思います。この場合、デフォルトで公開されています。私は答えを編集することができます。私は提案を編集するために開いています。方法については、私は完全にそれを理解しているか分からない。 'class A(val t:Int)'のようなものを使用し、 't'がクラスの属性/フィールドになる例は何ですか? –
'クラスA(i:Int)'を持つとき、クラス 'A'は' i'のためのフィールドを持ちません。 'i'は単なる(不変の)コンストラクタパラメータです。あなたが 'class A(i:Int){def foo = i}'を持つとき、クラス 'A'は' i'のための私有の不変フィールドを持っています。 –