• ベストアンサー

宣言していないクラス

畏れ入ります。 例外処理の勉強をしています。 例1の場合は class CarException extends Exception{ } とクラスを定義してから if(g<0){ //例外の条件です CarException e = new CarException(); throw e; としていました。 しかしふと、ほかの例題を見てこのように変えてみました /*クラス宣言削除/ if(g<0){ throw new CarException(); } これでもまったく同じ結果でした。 わからないのは、なぜこの場合には CarExceptionクラスの定義がないのに ”シンボルが解決できません” のコンパイルエラーにならないのでしょうか? newがついているから・・・というのはわかるんですが・・・ 初歩的な質問です、すみません

質問者が選んだベストアンサー

  • ベストアンサー
  • UKY
  • ベストアンサー率50% (604/1207)
回答No.4

> CarException e = new CarException(); > throw e; > > を、’e’というインスタンスの生成を省略すると、 > > throw new CarException(); > > となりそうですね(^.^) ちょっと誤解されているような気が…… 「インスタンス」と「変数」は同じものではありません。 この場合 e というのは変数であり、インスタンスそのものではないのです。 変数というのはあくまでもインスタンスへの参照を格納するものなのです。 (参照というのは、各インスタンスの ID ナンバーのようなものです。) たとえば、 String a, b; a = new String(); b = a; では、a と b の二つの変数が使われていますが、インスタンスそのものは一つしか生成していません。同じインスタンスへの参照が(つまり、同じ参照が)、異なる変数に代入されているだけなのです。 したがって、 CarException e = new CarException(); では、「CarException の新しいインスタンスの生成」と、「そのインスタンスの参照を変数 e に代入」という二つのことが行われているのです。 throw e; では、「変数 e に入っている参照に対応するインスタンスをスロー」がおこなわれ、 throw new CarException(); では、「CarException の新しいインスタンスの生成」と「インスタンスのスロー」が行われているのです。 省略されているのはインスタンスの生成ではなく、「変数の宣言と代入」です。 (わからなかったらどんどん補足してください。私自身この説明でわかっていただける自信がありません。)

azicyan
質問者

お礼

たびたびすいません_(._.)_ 勘違いしていました! 今、そういわれて、本を読み返していました。 なるほど、そう書いてあります。 new CarExceptionがインスタンスの生成で、CarException eは、あくまでも変数の定義なのですね。 変数eを使って作成したCarExceptionクラスのオブジェクトを扱うことができる。とありました。 勉強になりました ありがとうございます

すると、全ての回答が全文表示されます。

その他の回答 (3)

回答No.3

UKYさんが詳しく説明されているので、私は補足を。下 記の@ITのサイトによれば、 CarException e = new CarException(); は、new CarException();によって確保したメモリーの 先頭のアドレスを、eという変数に代入していることに なります。したがって、throw文でeを指定しようがnew CarException()が、同じメモリーをさしているので、同 じ結果になります。 http://www.atmarkit.co.jp/fjava/rensai2/javaent04/javaent04.html

参考URL:
http://www.atmarkit.co.jp/fjava/rensai2/javaent04/javaent04.html
azicyan
質問者

お礼

ありがとうございました m(__)m なんとなくわかりましたよ

すると、全ての回答が全文表示されます。
  • UKY
  • ベストアンサー率50% (604/1207)
回答No.2

「シンボルが解決できません」というエラーは、「指定した名前のクラスや変数が宣言されていない(見つからない)」ときに出ます。 例えば、 int i = Integer.parseInt("32"); という文があったとします。 この場合コンパイラは、前から順に、「int」「i」「Integer」「parseInt」はそれぞれクラスなのか、インタフェースなのか、変数なのか、メソッドなのか、ということを順次確認してゆくわけです。 これがもし int i = Integer.parseOnt("32"); というようになっていた場合、parseOnt という名前の変数もメソッドもありませんから、「parseOnt なんていうものは存在しませんよ」という意味で「シンボルを……」というエラーがでます。 ご質問のケースではどうでしょう。 throw new CarException(); という文において、CarException というクラスが正しく定義されている限りは、コンパイラが「CarException というのは Exception クラスのサブクラスなんだな」と確認できますので、エラーになることはありません。 さて、質問者さんの気にかかっているのは、なぜ変数を使わずにそのまま例外がスローできるのかということだと思います。しかし難しいことはまったくありません。 CarException e = new CarException(); throw e; については、「throw e;」で e という変数に入ったオブジェクトをスローするように命令があります。e というのは、直前で CarException の変数であると宣言しているので、問題なくコンパイルできます。 コンパイラは、「e は CarException クラスの変数で、これは例外クラスだから、それをスローするのは問題ない」と判断します。 ここでもし e が例外クラスでないクラスの変数であったりすると、「e は Throwable (のサブ)クラスではない」という意味で、「互換性のない型」というエラーになります。 さて、 throw new CarException(); についても深く考えることはありません。こちらでは、e という変数の中身ではなく、new CarException() という新しい例外のインスタンスをスローするような命令になっています。 先ほどではコンパイラは、「e は例外クラスの変数だから問題ないな」という判断をしていました。今回の場合では、「new CarException() は CarException というクラスのインスタンスだ。CarException は例外クラスだから、問題ないな」という判断をします。 new CarException() と書いた時点で、これはすでに CarException クラスのインスタンスであることは明白ですよね? new CarException() と書いて String クラスのインスタンスができるとは誰も思いません。

azicyan
質問者

お礼

とてもご丁寧な回答ありがとうございます。 うーん、ちょこっと難しいですが、やはりnewがみそですね。 CarException e = new CarException(); throw e; を、’e’というインスタンスの生成を省略すると、 throw new CarException(); となりそうですね(^.^)

すると、全ての回答が全文表示されます。
  • tediwec
  • ベストアンサー率70% (21/30)
回答No.1

同じディレクトリに CarException.class というファイルがありませんか? これを削除してコンパイルしてみるとエラーになると思います。

azicyan
質問者

お礼

ありがとうございます。 ちょっと違うようです(__)

すると、全ての回答が全文表示されます。

関連するQ&A