1

誰かが最初のコンストラクターなしの場合の出力0を説明できますかthis

引数変数名がクラスプロパティ名と同じで、メソッド内でそのプロパティを使用している場合。Javaはその「クラスプロパティ」または「引数変数」を何と解釈しますか?

なしthis

 public User(int userId){
    userId = userId;

 }

this

 public User(int userId){
    this.userId = userId;

 }


 public void PrintUserId(){
    System.out.println(this.userId);
}

 User firstUser = new User(123);
 firstUser.PrintUserId(); 

//これなしで0

//これで123

4

2 に答える 2

6

これがない最初のコンストラクターの場合、誰かが出力0を説明できますか?

確かに-このステートメントはノーオペレーションです:

userId = userId;

userIdパラメータの変数をそれ自体に割り当てるだけです。フィールドには全く触れません。メソッド内で、パラメーターは呼び出されたフィールドをuserId シャドウuserIdします-したがって、フィールドを参照することを明示的に指定する必要があります。これは、2番目のバージョンが行うことです。

this.userId = userId;

最近のIDEは、最初のバージョンのno-op割り当てを警告付きで強調表示することを期待しています。

(ちなみに、用語について明確にする価値があります。引数はメソッドに提供される値です。パラメーターは、メソッドのシグネチャの一部として宣言される変数です。同様に、プロパティではなくフィールドです。)

編集:パラメータの名前が異なる場合、例:

public User(int id) {
    userId = id;
}

その場合、パラメーターはフィールドをシャドウイングせずuserId、識別子は引き続きフィールドを参照します。識別子の意味を理解することがすべての問題です。最初の例では、単純な名前userIdはパラメータを参照しており、これが問題の原因です。

編集:JLSのセクション6.4.1から:

一部の宣言は、同じ名前の別の宣言によってスコープの一部がシャドウイングされる場合があります。その場合、宣言されたエンティティを参照するために単純な名前を使用することはできません。

..。

dのスコープ全体でのnシャドウという名前のフィールドまたは仮パラメーターの宣言d、dが発生するポイントでスコープ内にあるnという名前の他の変数の宣言。

したがって、この場合、dは正式なパラメーターの宣言であり、userIddのスコープはコンストラクターです。したがって、コンストラクター全体で、パラメーターはフィールドをシャドウイングします。

于 2012-04-15T18:59:30.343 に答える
4

これはシャドウイングが原因です。

userIdシャドウされているため、メンバー変数にパラメーター値を割り当てていません。メンバー変数は0に初期化されるため、キーワードintなしでその出力が表示されます。this

于 2012-04-15T19:01:37.347 に答える