コンパイルエラーと実行時エラーの区別がつきません
解決済
回答 4
投稿
- 評価
- クリップ 0
- VIEW 9,343
コンパイルエラーと実行時エラー、どちらが発生するのか、区別がつきません。
例えば以下の①②について、どうして①は実行時エラーで、②はコンパイルエラーとなるのかがわかりません。(どちらも同じような個所から1単語抜いただけなのに)
①mainメソッドから static を外した場合、コンパイルはできるが実行時エラーとなる
■ソースファイル
public class Sample1_1_3 {
public void main(String[] args) {
System.out.println("Hello!");
}
}
■コマンドプロンプト
c:\sample\chap01>javac Sample1_1_3.java
c:\sample\chap01>java Sample1_1_3
エラー: メイン・メソッドがクラスSample1_1_3のstaticではありません。次のようにメ
イン・メソッドを定義してください。
public static void main(String[] args)
②mainメソッドから void を外した場合、コンパイルエラーとなる
■ソースファイル
public class Sample1_1_4 {
public static main(String[] args) {
System.out.println("Hello!");
}
}
■コマンドプロンプト
c:\sample\chap01>javac Sample1_1_4.java
Sample1_1_4.java:2: エラー: 無効なメソッド宣言です。戻り値の型が必要です。
public static main(String[] args) {
^
エラー1個
以上、ご教示のほどよろしくお願いいたします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+7
コンパイルエラーは、コンパイラがそのコードを読み解くことができない状態のことを言います。
メソッドを記述するルールは明確に決まっており、
[アクセス修飾子(publicなど、省略可)] [static(省略可)] [返り値の型(voidやintなど)] [メソッド名]([引数の型 仮引数名(任意の数)])
このルールにわずかでも反するものはコンピュータは解読することができません。そのほか、言語のルールにのっとっていないものはコンパイラが解読することができないため、コンパイルエラーとなります。
②の場合は、voidを外したことにより「返り値の型」として解釈できるものがなくなってしまった(語順的にはmainが該当するがそんな型は存在しないし、そうだとしても今度はメソッド名がなくなる)ので、コンピュータが解読できなくなり、コンパイルエラーとなります。
言語上のルールにのっとっているものはコンパイルすることができます。しかし実際に動かしてみると、プログラムの実行が続行できない状況が発生することがあります。これが実行時エラーです。nullに対してメソッドを起動しようとすることや、整数を0で割ろうとしたりすることなどが該当します。コンパイラはあくまで文法上の問題をチェックするのみで、そういったところまではケアしません。
①の場合、staticは無くてもメソッドの書式には反しない(上記の通りstaticは省略可)ため、コンパイルすることができます。しかし実行する際、public static void main(String[])
メソッドから始めると決まっているにも関わらず、実行しようとしているクラスでそれが見つからないため、実行時エラーとなるのです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+4
①mainメソッドから static を外した場合、コンパイルはできるが実行時エラーとなる
main メソッドは static でも static で無くても, java のコードとしては普通のメソッドと同じですので, コンパイル出来ます.
コンパイル時点では, クラス内に記述されている main メソッドが実行するためのものかはコンパンラは分かりません.
実行時にクラス名が指定されて初めて main メソッドが実行するためのものだったことが分かるので, 実行時にエラーになります.
②mainメソッドから void を外した場合、コンパイルエラーとなる
メソッドは戻り値の型が必要です.
void を外すと型が無くなるので, コンパイルでエラーとなります
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
文法的におかしいのはコンパイルエラーとなります
文法的にあってるんだけど、実行時におかしいのは実行時エラーとなりますね
区別がつかないというのは、まだJAVAの文法をしっかり習得してないからですね
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
コンパイルエラー:
Compile-Error. コンパイルが解釈不可能な状態.
実行時エラー:
Runtime-Error. 実行時にクラッシュしたり実行結果がおかしい場合.
です。
コンパイルエラーは、コンパイルが解釈するときに「??? 何言ってんの?」ってなる状態。
例えばJavaでもC++でもそうだけど、型が厳格な言語で、
// 変数宣言なしで
a = 10;
としたら、a = 10 の行で「コンパイルエラー」を吐く。
人間からすると変数ってこともわかるし、10を代入していることから整数系( int, long 等 ) だろうと想定できる。
しかし、コンパイラは定義された方法以外では解釈できない。
人間の私たちが宇宙人語(ある・ないはともかく)を理解できますか?
これイコールこれと定義付ける必要があるでしょ?
それと一緒。
だから、「aっていう変数? よくわからんがそんなもん、ないよ?」と怒られる。
これがコンパイルエラー。つまり、for文の書き方とか変数宣言していないとかのような、解釈そのものができない状態に出る。
実行時エラーは、コンパイルは通る(= 構文は正しい )が、意味的におかしい場合です。
例えばテストの点数を数学・国語・理科・社会・英語の順番に入力して、合格/不合格 を表示するプログラムだとして、
なおかつ、
合格 : 70%以上
不合格: 合格基準を満たしていない場合
とした場合、本来なら80%あるとしたら、70%以上に該当するから "合格"が印字されるはず。
でも実際には"不合格"となっていたりする。
この場合は、構文的には正しいけど、if文での 大なり・小なりとかのやつがおかしかったりする。
合格: 70%以上
とするなら、
// int pers にパーセンテージの数字が入っているとして
if( pers >= 70 ){
// 合格
}
とするところを、
// int pers にパーセンテージの数字が入っているとして
if( pers <= 70 ){
// 合格
}
// => "pers が 70以下のとき" と解釈される
という風に意味が違う。
あと、C++, Javaとかの例外処理が備わっている言語だと、
例外エラーもある。
これはどっちにはいるのかわからんが、メッセージに
"Exception" とか "例外" っていう字が入っている。
NullPointerException (いわゆる"ぬるぽ") とか。
ここまでが基礎。
で、質問を読むと、
Q1. 実行時エラー?
public class Sample1_1_3 {
public void main(String[] args) {
System.out.println("Hello!");
}
}
となっている。
確かにコンパイルは通るはず。
でも実行ができない。
これは知識不足によるものですね。
なぜコンパイルが通るのか。
それは「普通のクラスと解釈された」から。
普通のクラスでも一応mainメソッドを持つことは可能だと思う。
でも、Javaはclassファイルそのものが動いているのではなくて、
Java.exe っていうソフト ( JDKやユーザ向けのJAVAに入っているやつ ) が解釈します。
根拠は、
C言語でコマンドライン引数と呼ばれるものを受け取る場合、
rem main.exe が実行ファイルだとして
main -a -b -f=file1.jpg
のような感じになる。
ではJavaだとどうなるか。
rem Main.class がメインメソッドがあるクラスファイルだとして
java Main -a -b -f=file1.jpg
となる。
Java.exe に Main.class を渡して、それと -a -b ... とかも渡す。
という状態。
だから、曲を書く人が音符のやつ書いて、それを指揮者とか楽器演奏者に渡してやってもらう。
みたいな状態。
で、話を戻して、
Java.exe が 渡されたクラスやJarファイルを参照して処理する。
だからmainメソッドから開始するけど、
決められた書き方以外では認識できない。
だからエラー。
これが実行時に行われているから"実行時エラー".
二つ目のやつは、voidがないって...これはコンパイルが解釈できない。
必ず メソッドは型を持つ。
それを定義しないから、変数宣言がないとか、ありもしないメソッドを使おうとしている...みたいな感じのエラーになる。( エラー理由が違うが、「解釈できない」っていう意味では同じ。 )
まずは基礎部分から理解しましょう。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.09%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
BeatStar
2019/04/12 11:50
コードは"<コード>"ボタンを押して、出てきたものに書きましょう。
今回は行数が少なめなのでいいですが、行数が多くなると(特に入れ子状態になると)
かなり読みにくくなります。