こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

「Javaのクラスメソッド内でsuperキーワードは使える?」

「Javaのクラスメソッド内でsuperキーワードは使える?」
Java言語仕様(第2版日本語訳初版)(注)の以下の記述をどう解釈するべきでしようか? 


「8.4.6継承、オーバーライド、隠蔽」>「8.4.6.2隠蔽(クラス・メソッドによる)」において、staticメソッドがシグネチャが同じスーパークラスのメソッドを隠蔽し、それがインスタンスメソッドであればコンパイルエラーになる、との記述のあと、下記のような記述があります。

『隠蔽されたメソッドは、限定名、あるいはsuperキーワードやスーパークラス型へのキャストを含んだメソッド起動($15.12)を使用することによりアクセスすることができる』

まるで、「インスタンンスメソッドと同じようにクラスメソッドにおいてもsuperキーワードを使用することでスーパークラスのstaticメソッドを呼び出せる」ように読み取れます。

ちなみに該当部分の原典は、

 http://java.sun.com/docs/books/jls/download/langspec-2.0.pdfから抜粋
 8.4.6.2 Hiding (by Class Methods)
(略)
 A hidden method can be accessed by using a qualified name or by using a
 method invocation expression (§15.12) that contains the keyword super or a cast
 to a superclass type. In this respect, hiding of methods is similar to hiding of
 fields.

また、第3版原典も該当部分は同じ記述でした。
 http://java.sun.com/docs/books/jls/download/langspec-3.0.pdf
 8.4.8.2 Hiding (by Class Methods)

なお、superキーワードについては、同書 15.11.2 「superを使用したスーパークラスのメンバへのアクセス」の項で、

『superキーワードを使用した特殊形式は、インスタンス・メソッド、インスタンス初期化子、コンストラクタ、あるいはクラスのインスタンス変数の初期化子中でのみ有効となる』

とあり、クラスメソッド中では使えないと読み取れます。(続けて、 superとthisの使用条件は全く同じ、としています。)

Javaコンパイラは、クラスメソッド中のstaticキーワードを認識せず、エラーとします。

諸兄のお考えをお聞かせください。

注)http://www.amazon.co.jp/Java%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98-Java-%E3%82%B8%E3%82%A7%E3%83%BC%E3%83%A0%E3%82%BA-%E3%82%B4%E3%82%B9%E3%83%AA%E3%83%B3/dp/4894713063/ref=sr_1_2?ie=UTF8&s=books&qid=1270203134&sr=1-2

投稿日時 - 2010-04-02 19:14:19

QNo.5797883

暇なときに回答ください

このQ&Aは役に立ちましたか?

3人が「このQ&Aが役に立った」と投票しています

回答(2)

ANo.2

>((Parent(this)).print();は
>((Parent)this).print();・・・thisへのスーパークラス型へのキャスト
>でよろしいでしようか?

そのとおりよ。
コピペで書いたから変なところに括弧がついちゃったわね。
ゴメン。

投稿日時 - 2010-04-04 14:30:41

お礼

askaaskaさま、こんにちは。
これを機に、オーバーライド(動的束縛)と隠蔽(静的束縛)を意識するようになりました。
ありがとうございました。

投稿日時 - 2010-04-04 15:19:19

ANo.1

> 「8.4.6継承、オーバーライド、隠蔽」>「8.4.6.2隠蔽(クラス・メソッドによる)」において
> staticメソッドがシグネチャが同じスーパークラスのメソッドを隠蔽し、
> それがインスタンスメソッドであればコンパイルエラーになる

class Parent {
void print() {
System.out.println("Parent");
}
}
class Child extends Parent {
static void print() {
System.out.println("Child");
}
}

> 『隠蔽されたメソッドは、限定名、あるいはsuperキーワードやスーパークラス型へのキャストを
> 含んだメソッド起動($15.12)を使用することによりアクセスすることができる』
class Parent {
static void print() {
System.out.println("Parent");
}
}
class Child extends Parent {
static void print() {
System.out.println("Child");
}
void print2() {
Parent.print();
super.print();
((Parent(this)).print();
}
}


上記のコードでわかってもらえるといいんだけど。

投稿日時 - 2010-04-02 20:49:45

補足

askaaskaさま、こんばんは。

[8.4.6.2]隠蔽(クラス・メソッドによる)というタイトルから、
≪隠蔽されたクラスメソッド[上記Parent:print()]を、隠蔽したクラスメソッド[上記Child:print()]内からsuperを使ってアクセスできる≫という主張かと思っていたのですが、

そうではなくて、隠蔽されたクラスメソッドにアクセスする方法として、場合に応じていろいろな方法があり、その一つとして、サブクラスのインスタンスメソッドにおいては、上記Child:print2()にある3通りのような方法がある と理解すべきなのですね。

ご回答ありがとうございました。

細かいことですが、上記print2()の
((Parent(this)).print();は
((Parent)this).print();・・・thisへのスーパークラス型へのキャスト
でよろしいでしようか?

投稿日時 - 2010-04-02 22:21:20

あなたにオススメの質問