Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

メソッドローカルな無名クラスの呼び出し

お世話になります。
class MyClass{
    void method1(){
        new Object(){
            void disp(){
                System.out.println("Hello");
            }
        }
        .disp();
        //.disp();
        class InnerClass{
            void disp(){
                System.out.println("InnerClass");
            }
        }
        new InnerClass().disp();
        new InnerClass().disp();
    }
}
class Test{
    public static void main(String args[]){
        MyClass my = new MyClass();
        my.method1();
    }
}

上記プログラムで、//.disp();のコメントをはずすと
式の開始が不正です。となりコンパイルエラーとなります。
無名クラスのdisp()を使って、下記の実行結果の様にするにはどうすれば良いでしょうか。
Hello
Hello
InnerClass
InnerClass

よろしくお願いいたします。

21

回答

80474

閲覧

21件の回答

評価

0

インスタンス化せずにインスタンスメソッドが呼べるわけがない。

評価

0

最初の.disp()は実際にはnew Object(){...}.disp()だってこと。

評価

0

ご回答ありがとうございました。
理解致しました。
参考書を読み進めて行くと、同じ事が書いてありました。
申し訳ありません。

何度も実行するには、インスタンスのアドレス情報を参照型変数に代入してやると、メソッド内で、何度でも使えるというあたりも理解しました。

ありがとうございます。

評価

0

括弧をつけたほうが、わかりやすいんじゃないかな。
ついでに尻尾を補完。

(new Object(){...}).disp();
   <なんもなし>    .disp(); //<-コンパイルエラー

評価

0

2010-02-24 16:22
>インスタンス化せずにインスタンスメソッドが呼べるわけがない。

最初の.disp()はインスタンス化されていますよね。
二回目の.disp()はインスタンスメソッドではなく、不正な式。
つまり『インスタンス化せずに』ではなく、不正な式を呼べるわけがないって事ですよね。

あってますか?

評価

0

違いますか^^;

評価

0

そんな不正な式を、なぜ書いたのか。
その原因は無視なのかい?

俺にいわせれば、
そのことと比べたら、不正な式になってしまった結果なんぞ、
それこそどうでもいいんだが。

評価

0

なぜ不正な式なのかは、2010-02-24 16:24で理解しました。

2010-02-24 16:22
>インスタンス化せずにインスタンスメソッドが呼べるわけがない。
↑のインスタンス化せずにってところがあっているのかどうかが知りたいと思ったのです。

インスタンスメソッドではない<なにもなし>.disp()をインスタンス化せずにっていうのはおかしいかなぁと疑問に思ったので質問致しました。

評価

0

1.メソッド内部でのclass 宣言は不可能

2.無名クラス 「new Object(){...}」はclass Object とは等価ではない。

3.メソッドの呼び出しは [オブジェクト参照.]メソッド名称(パラメータ)である。
「.」から始まる場合はない。




前述のように new Object() { ... } にてインスタンスかされたオブジェクトに対し dips()を実行しろと命令はしているが2番目に関しては

その対応するオブジェクトが存在しない。

よってコンパイルエラーになる。

評価

0

>インスタンスメソッドではない

じゃあクラスメソッド? でもないしな。

知識がついたからって、先の失敗を
棚上げにしようとしてる、ようにしか見えないんだけど。

まあ、どうでもいいです。

評価

0

棚上げしようとはしておりません。
詳しく知りたかっただけなんです。

.がついてるので、クラスメソッドでもないですね。
.がついてなくても見つからないですし。


『どうでもいい』ってフレーズ好きですね。
どうでもいいなら回答して頂かなくてもいいですよ。
どうでもいいですけど。

評価

0

2010-02-24 17:29
>1.メソッド内部でのclass 宣言は不可能
メソッド内部とはメソッドローカルですか。
インナークラスの宣言はできますよね。

すいません、理解できないので、もう少し詳しくご説明お願いします。

評価

0

これに対する回答がないよ。

>そんな不正な式を、なぜ書いたのか。

要するに、インスタンスメソッドを、
インスタンス化もせずに呼び出そうとしてたんだろ、
ってこった。

評価

0

んー。

インスタンスメソッドはインスタンス化しないと使えない。
1つ目はぱっと見ではインスタンスと関係ないように見えないこともないが、実際にはちゃんとしているということ。

評価

0

最近の質問者さんのパニクり具合がおもしろいなぁ。

回答者さんたちの回答が禅問答にみえるくらいでw

javarさんの(2010-02-24 16:50)でまぁ、それで間違ってはないですけど
それに対して指摘している不良社員さんの3つめの回答(2010-02-24 17:20)の解説を勝手にしてみる

「なぜ不正な式」じゃなくて「なぜ不正な式を書いたかの原因」
(で、あってますよね?)

おそらく、根本的なことで思い込んでいるんじゃぁないかと思われることが一つあります。


今まで、中括弧({})が閉じられた場合、次に出てくる文は中括弧とは分離されるという認識だったのでは?
(もしかして、今もでしょうか?)
その認識のため、「.disp();」が次の行に出てきた時に、ひとつの書き方として解釈してしまっていたのでしょう。
今回出てきている中括弧は今まで出てきたif文やメソット文を囲むためだけの中括弧とは性質が少し違いますよ。
なので、「;」で本当に分離されたあとに、「.disp()」っていうのを単独で使用しようという考え方は間違っているのですよ。

評価

0

>今まで、中括弧({})が閉じられた場合、次に出てくる文は中括弧とは分離されるという認識だったのでは?
そういう認識でした。

>その認識のため、「.disp();」が次の行に出てきた時に、ひとつの書き方として解釈してしまっていたのでしょう。
仰る通りです。
無名クラスという事から、<無名クラス/なにもない>.disp();と書くと無名クラスのdisp()が呼び出せると思ったのです。
で、二つ書くとHelloと二回結果として出力されると思っていました。

ただ上記の事は2010-02-24 17:27で理解したつもりだったのですが。
決して「なぜ不正な式を書いたかの原因」を無視していた訳じゃないです。





評価

0

2010-02-25 16:11
>ただ上記の事は2010-02-24 17:27で理解したつもりだったのですが。
決して「なぜ不正な式を書いたかの原因」を無視していた訳じゃないです。

2010-02-24 17:27 誤
2010-02-24 16:24 正

評価

0

>ただ上記の事は2010-02-24 17:27で理解したつもりだったのですが。

2010-02-25 16:11までかかったわけだね。

要するに、スレ主さんは、
文法間違いだから、文法間違いなんですよね、
とレスしていた『だけ』なのに、
俺は、んな当たり前のことなんぞどうでもいいから、
原因の方に目を向けろよ、とやって、
すれ違っていた訳か。

これさえなかったら、『だけ』ってのは認めてもいいんだがな。

>2010-02-24 16:50
>つまり『インスタンス化せずに』ではなく、

じゃ、俺はこのへんで。ノシ

評価

0

△ インスタンス化せずにインスタンスメソッドが呼べるわけがない。

○ インスタンスを指定せずにドット付きインスタンスメソッドを呼べるわけがない。

◎ ドットから始まるメソッド呼び出しは存在しない。(ドットを付けるときはクラスかインスタンスを必ず指定する必要がある。ドットを付けなければ自クラスのメソッド呼び出しとして解釈される。)

「インスタンス化せず」という指摘は少し分かりにくかったと思います。無名クラスのインスタンス化 new Object() {...} もしているし、MyClass のインスタンス化もしていますから。

インスタンス化はしているのに、肝心のメソッド呼び出しのときに「作成したインスタンスを指定していない」というのがポイントだと思います。

質問者は無名クラスという名前から「スコープ内で永続化されて、以降、メソッド名だけで呼び出せるような存在」と考えてしまったようですね。(import static のインスタンス版みたいな?) 私は、なるほどと思いました。

評価

0

すっきりしました。
私の無知でご迷惑お掛けして申し訳ないです。

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

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。