- PR -

superやthisなどの修飾子についてお聞きします

投稿者投稿内容
さる
ぬし
会議室デビュー日: 2005/07/14
投稿数: 276
お住まい・勤務地: 実家戻ったw
投稿日時: 2007-04-24 16:52
引用:

nagiseさんの書き込み (2007-04-24 16:35) より:
メソッドは当然分かるのですが、問題はフィールドですね。
static finalなものは命名規約が違うので分かりやすいのですが、
インスタンスのフィールドもstaticなフィールドも名称は変わりません。
コード:
public class Hoge {
  private Object hogeInstance = new Object();
  private static Object hogeStatic = new Object();

  public static void main(String[] args) {
    Hoge hoge = new Hoge();
    System.out.println(hoge.hogeInstance); // インスタンス変数へのアクセス
    System.out.println(hoge.hogeStatic); // 一見して分からないが実はスタティック変数へのアクセス
  }
}



教育期間にある新人プログラマにはthisを付けるように指導しています。
thisを付けさせることで、それがインスタンス対する操作なのか、
クラスにたいする操作なのかを意識させることが重要だと思います。



どうもSunのコーディング規約が結構染み付いちゃってるんで上記のような場合を忘れてました。

引用:

10.2 Referring to Class Variables and Methods
Avoid using an object to access a class (static) variable or method. Use a class name instead. For example:

classMethod(); //OK
AClass.classMethod(); //OK
anObject.classMethod(); //AVOID!

10.2 クラス変数とクラスメソッドの参照
クラス変数(static な変数)やクラスメソッド(static なメソッド)には,特定のインスタンスを使ってアクセスするべきではない.クラス名を使うようにする.例を示す.

classMethod(); // オッケー
AClass.classMethod(); // オッケー
anObject.classMethod(); // これはダメ!



新人君にはSunのコーディング規約を徹底させてるので、
hoge.hogeStatic
をやった時点で説教開始ですね。
まあ、今はEclipseで開発が多いので大抵警告してくれるし。

Innerクラスは・・・例であげられてるコードはコンパイルを通らないですね。
コピペしてみたけど通らない。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2007-04-24 17:07
実はこんなコードもコンパイルが通ってしまうので注意が必要です。
コード:
class Foo{

    static int bar = 0;

    void bar(){
        this.bar = 1;
    }
}

class Bar{

    void foo(){
        Foo foo = null;
        foo.bar = 2;
    }
}


Eclipseできちんと警告を出すようにすれば問題ないのですが。

#どんどん話がそれたり、揚げ足取りのような気も・・・すいません。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-04-24 17:18
Sunの規約に沿っていたとしても
コード:
public void Hoge {
  private int instanceHoge;
  private static int staticHoge;

  /** インスタンスメソッド */
  public void hoge() {
    System.out.println(instanceHoge); // インスタンス変数
    System.out.println(staticHoge); // static変数
  }
}


と、インスタンスメソッド内では混同しますよね。
そもそも新人がstatic変数を宣言しないといけない必然性のあるコードを
書くことなんてまずないのですけどね。

このあたりのひっかけについては
「JAVA PUZZLERS」 ISBN:4-89471-689-5
が詳しいです。
さる
ぬし
会議室デビュー日: 2005/07/14
投稿数: 276
お住まい・勤務地: 実家戻ったw
投稿日時: 2007-04-24 18:10
引用:

かつのりさんの書き込み (2007-04-24 17:07) より:
実はこんなコードもコンパイルが通ってしまうので注意が必要です。
コード:
class Foo{

    static int bar = 0;

    void bar(){
        this.bar = 1;
    }
}

class Bar{

    void foo(){
        Foo foo = null;
        foo.bar = 2;
    }
}


Eclipseできちんと警告を出すようにすれば問題ないのですが。


それこの前やってくれましたw<新人君
とりあえずややこしくなるのでInnerクラスには触れずに
「規約見て、javaファイルにはクラスは一個だけにしてね」と言いましたね。

引用:

nagiseさんの書き込み (2007-04-24 17:18) より:
Sunの規約に沿っていたとしても


引用:

クラス変数(static な変数)やクラスメソッド(static なメソッド)には,特定のインスタンスを使ってアクセスするべきではない.クラス名を使うようにする.



クラス名使ってないから説教開始で撃墜♪
作業する前にはそういう書き方しないように徹底指導ですね。

まあ、Sunに規約に沿うというのがEclipseで警告が出ないと同意だったら
確かに警告は出してくれないですね。

ついでにthisつけなきゃ駄目にするんだったら
Eclipseだったら
エラー/警告
コードスタイル
インスタンスフィールドへの限定されていないアクセス(Q)
を警告やエラーにすれば良いはずっすね。
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-04-24 20:18
引用:

さるさんの書き込み (2007-04-24 18:10) より:
引用:

nagiseさんの書き込み (2007-04-24 17:18) より:
Sunの規約に沿っていたとしても


引用:

クラス変数(static な変数)やクラスメソッド(static なメソッド)には,特定のインスタンスを使ってアクセスするべきではない.クラス名を使うようにする.



クラス名使ってないから説教開始で撃墜♪
作業する前にはそういう書き方しないように徹底指導ですね。



たとえばクラスHogeからクラスPiyoのstaticフィールドを
アクセスする際はPiyo.piyoとするでしょうが、
私が例に挙げたようにHogeクラス内でHogeクラスに定義されている
sataticフィールドにアクセスする
際にクラス名を書いているでしょうか?
先のページでは自分のクラスの場合は省略することを許容していましたね。
引用:

classMethod(); // オッケー
AClass.classMethod(); // オッケー
anObject.classMethod(); // これはダメ!


メソッドしか例が挙げられていませんでしたが、変数とメソッドを一緒くたに
説明されていましたからフィールドも同等で自分のクラスは省略可でしょう。

自分のクラスに定義されたstaticフィールドにアクセスする際に自分のクラス名を
省略しないで書くようにしているなら問題ないですが、そうしてます?
継承関係にあるクラスで親で定義されているstatic変数にアクセスする際も
定義されている階層のクラス名をつけています?
クラス名を省略してフィールドアクセスしている方が多いのではないでしょうか。
(規約でも許容していますし)

Eclipseも最近では構文解析してのカラーリングがデフォルトになっているので
スタティック変数か、インスタンス変数かが一目で分かるようになりました。
昔はマシンスペックとの兼ね合いもあってデフォルトではOFFでしたね。(Eclipse2.x系)

玉石混合の開発メンバーにおいて如何に未然にバグを抑えるかというのは難しいテーマですね。
さる
ぬし
会議室デビュー日: 2005/07/14
投稿数: 276
お住まい・勤務地: 実家戻ったw
投稿日時: 2007-04-25 10:47
引用:

nagiseさんの書き込み (2007-04-24 20:18) より:
たとえばクラスHogeからクラスPiyoのstaticフィールドを
アクセスする際はPiyo.piyoとするでしょうが、
私が例に挙げたようにHogeクラス内でHogeクラスに定義されている
sataticフィールドにアクセスする
際にクラス名を書いているでしょうか?
先のページでは自分のクラスの場合は省略することを許容していましたね。
引用:

classMethod(); // オッケー
AClass.classMethod(); // オッケー
anObject.classMethod(); // これはダメ!


メソッドしか例が挙げられていませんでしたが、変数とメソッドを一緒くたに
説明されていましたからフィールドも同等で自分のクラスは省略可でしょう。

自分のクラスに定義されたstaticフィールドにアクセスする際に自分のクラス名を
省略しないで書くようにしているなら問題ないですが、そうしてます?
継承関係にあるクラスで親で定義されているstatic変数にアクセスする際も
定義されている階層のクラス名をつけています?
クラス名を省略してフィールドアクセスしている方が多いのではないでしょうか。
(規約でも許容していますし)

Eclipseも最近では構文解析してのカラーリングがデフォルトになっているので
スタティック変数か、インスタンス変数かが一目で分かるようになりました。
昔はマシンスペックとの兼ね合いもあってデフォルトではOFFでしたね。(Eclipse2.x系)

玉石混合の開発メンバーにおいて如何に未然にバグを抑えるかというのは難しいテーマですね。



あら・・・すいません、規約を私が勘違いしてたようですね。
staticのフィールド・メソッドはクラスからアクセスしないと駄目だと思っていました。
例では確かに許容してますね。
今まで新人君に「必ずstaticはクラス名を書いてアクセスしてね」と教えてました。
失礼致しました。

スキルアップ/キャリアアップ(JOB@IT)