twilight1730の資料室(wiki別館)

Java雑記001(とりあえず色々コンパイルしてみる)

最終更新:

twilight1730

- view
管理者のみ編集可

目次


  • 前置き

  • 構文ミス(一部正規あり)とコンパイル/実行時の挙動

  • コンパイル/実行自体のミス

はじめに


 Javaについてプログラミングをして気になったことなど、忘れたときにメモするためのページ。ブログに書けって話ですが、アットウィキのhilightプラグインが優秀っぽいので、アットウィキにて書いていきます。




HelloWorldプログラムを作ってみる


 有名なプログラム"HelloWorld"を作ってみます。まずどのプログラミング言語でも最初に作るプログラムで、単純にコンソールで起動すると"Hello, World!"と表示して終わるだけのプログラムです。


HelloWorld.java
  1. public class HelloWorld{
  2. public static void main(String[] args){
  3. System.out.pringln("Hello, World!");
  4. }
  5. }


  • コンパイル

 
C:\Java\HelloJava>javac HelloWorld.java

C:\Java\HelloJava>
 


  • 実行

 
C:\Java\HelloJava>Java HelloWorld
Hello, World!

C:\Java\HelloJava>
 

以下いくつかわざとエラーを起こしてみました





1.public class ではなく class で宣言


  • ソースコード
HelloWorld.java
  1. class HelloWorld{
  2. public static void main(String[] args){
  3. System.out.pringln("Hello, World!");
  4. }
  5. }
  • コンパイル
 
C:\Java\HelloJava>javac HelloJava.java ※コンパイルエラーにはならない

C:\Java\HelloJava>
 
  • 実行
 
C:\Java\HelloJava>java HelloJava
Hello, World!

C:\Java\HelloJava>
 

なぬ実行されたΣ(゚д゚;)
ちょっと予想外でしたがやらないほうが良いですね…ハイ
(publicメソッドが関係してるのか・・・?)


2.class名をファイル名と違うものにする


  • ソースコード(HelloWorld.java)
  1. public class Main{
  2. public static void main(String[] args){
  3. System.out.pringln("Hello, World!");
  4. }
  5. }
  • コンパイル
 
C:\Java\HelloWorld>javac HelloJava.java
HelloWorld.java:1: エラー: クラスMainはpublicであり、ファイルMain.javaで宣言する必要があります
public class Main{
        ^
エラー1個
 

こちらはコンパイル時にエラーが吐き出されます。必ずひとつのjavaファイル内にはひとつのpublicクラスのみ宣言可能で、必ずファイル名と同じクラス名である必要があります。


3.mainメソッドをstaticなしで宣言


  • ソースコード(HelloWorld.java)
  1. public class HelloWorld{
  2. public void main(String[] args){
  3. System.out.pringln("Hello, World!");
  4. }
  5. }
  • コンパイル
 
C:\Java\HelloJava>javac HelloJava.java ※コンパイルエラーにはならない

C:\Java\HelloJava>
 
  • 実行
 
C:\Java\HelloJava>java HelloJava
エラー: メイン・メソッドがクラスHelloWorldのstaticではありません。次のようにメイン・メソッドを定義してください。
  public static void main(String[] args)

C:\Java\HelloJava>
 

外側からクラスに属するmainメソッドを実行しなければならないので、実態が必要となるインスタンスメソッドでの宣言では呼び出すことが出来ません。


4.引数を持たないmainで定義してみる


  • ソースコード(HelloWorld.java)
  1. public class HelloJava{
  2. public static void main(){
  3. System.out.println("Hello, World!");
  4. }
  5. }
  • コンパイル
 
C:\Java\HelloJava>javac HelloJava.java ※コンパイルエラーにはならない

C:\Java\HelloJava>
 
  • 実行
 
C:\Java\HelloJava>java HelloJava
エラー: メイン・メソッドがクラスHelloWorldで見つかりません。次のようにメイン・メソッドを定義してください。
  public static void main(String[] args)

C:\Java\HelloJava>
 

やはりダメです。たとえ引数を必要としないmainメソッドでも、引数を内部で無視しようが無視しまいが、たとえ引数がないにせよ、String配列を渡してくるわけです。必ず文字列配列を受け取るメソッドとして定義しましょう。


mainメソッドの戻り値をvoid型以外にしてみる


  • ソースコード(HelloWorld.java)
  1. public class HelloJava{
  2. public static int main(String[] args){
  3. System.out.println("Hello, World!");
  4. }
  5. }
  • コンパイル
 
C:\Java\HelloJava>javac HelloJava.java ※コンパイルエラーにはならない

C:\Java\HelloJava>
 
  • 実行
 
C:\Java\HelloJava>java HelloJava
エラー: メイン・メソッドはクラスHelloWorldのvoid型を返す必要があります。次のようにメイン・メソッドを定義してください。
  public static void main(String[] args)

C:\Java\HelloJava>
 

たとえvoid型であろうがvoid型自体もひとつの型です。Javaインタプリタ側ではvoid型以外の戻り値は拒否するようです。(自作クラスのメソッドが戻り値を必要としないのにint型などで戻り値を返しても普通は代入相手が居なければ切り捨てられますが、mainメソッドはそうではないようです)


6.パラメータ変数名を変えてみる


  • ソースコード(HelloWorld.java)
  1. public class HelloJava{
  2. public static int main(String[] foo){
  3. System.out.println("Hello, World!");
  4. }
  5. }
  • コンパイル
 
C:\Java\HelloJava>javac HelloJava.java

C:\Java\HelloJava>
 
  • 実行
 
C:\Java\HelloJava>java HelloJava
Hello, World!

C:\Java\HelloJava>
 

 このコードは全く問題がありません。そもそも変数名は入れ物を区別するための名前であって、さらに引数として宣言した変数はパラメータ変数としてメソッド内でのみ有効なものなので、たとえ変数名が何であろうと外から実効する分には全く問題がありません。なのでこのコードは問題なく動きます。

 ただし慣例的にmainメソッドの引数はargs(argumentsの略)で受け取るものとしてコードが書かれます。そのような通例には従っておいた方が他の人が見たときに分かりやすく、自分も再度コードを見たときに分かりやすいなります。特別な理由がない限りなるべくmainメソッドの受け取るString配列の変数名はargsにしてください。(尚、C言語はargc=配列の長さ、argv=引数の配列で宣言することが多いです。Javaでは配列の長さを引数の配列から調べることが出来るので配列長は受け取る必要がありません。)


7.mainメソッド内でreturn文を使う


  • ソースコード(HelloWorld.java)
  1. public class HelloJava{
  2. public static int main(String[] args){
  3. System.out.println("Hello, World!");
  4. return;
  5. }
  6. }
  • コンパイル
 
C:\Java\HelloJava>javac HelloJava.java

C:\Java\HelloJava>
 
  • 実行
 
C:\Java\HelloJava>java HelloJava
Hello, World!

C:\Java\HelloJava>
 

 void型のメソッドの場合、戻り値を必要としないためreturn文は必要ありません。ただしreturn文を引数なしで使った場合void型を返すことが出来ます。戻り値void型のメソッド内で条件分岐しある場合のみ先にメソッドを抜けたい場合などはreturn文を使います。ともあれ、void型の戻り値を期待するメソッドで引数のないreturn文を使うことは問題ありません。(尚、int型メソッドなど、戻り値を期待するメソッドでreturn文がないとエラーになります)





1.javac 間違ったjavaファイル名


  • コンパイル
 
C:\Java\HelloWorld>HalloWorld.java
javac: ファイル名が見つかりません: HalloWorld.java
使用方法: javac <options> <source files>
使用可能なオプションのリストについては、-helpを使用します

C:\Java\HelloWorld>
 

 ファイル名を間違えた場合は「ファイルが見つかりません」と言われます。あるはずなのにないといわれたらファイル名が間違っているか探しているフォルダが間違っている可能性があります。このエラーが出たらよく確認してみてください。


2.コンパイルするつもりでjavaコマンドを使ってしまった場合


  • コンパイル(のつもり)
 
C:\Java\HelloWorld>java HelloWorld.java
エラー: メイン・クラスHelloWorld.javaが見つからなかったかロードできませんでした

C:\Java\HelloWorld>
 

javaコマンドにjavaファイル名を渡してしまった場合は、インタプリタは"ファイル名.java.class"というクラスファイルを捜索します。もちろんそんなものありませんので「見つからないよ」とエラーを吐き出します。



3.java クラス名.class を使った場合


  • 実行
 
C:\Java\HelloWorld>java HelloWorld.java
エラー: メイン・クラスHelloWorld.classが見つからなかったかロードできませんでした

C:\Java\HelloWorld>
 

 先ほどと同様です。見つからないので実行も出来ません。"class"は予約語なので、このような呼び出しをすることも絶対にありません。


4.実行するつもりでjavacコマンドを使った場合


  • 実行(のつもり)
 
C:\Java\HelloWorld>javac HelloWorld
エラー: クラス名'HelloWorld'が受け入れられるのは、注釈処理が明示的にリクエストされた場合のみです
エラー1個

C:\Java\HelloWorld>
 

 明示的にリクエスト・・・?ちょっとこの辺の理解が足りなくて恐縮ですが、コンパイルエラーが吐き出されます。


実行のつもりでjavacコマンドを使った上にクラス名.class


  • ???
 
C:\Java\HelloWorld>javac HelloWorld.class
javac: HelloWorld.classは無効なフラグです
使用方法: javac <options> <source file>
使用可能なオプションリストについては、-helpを使用します

C:\Java\HelloWorld>
 

 もはや何がしたいのかって間違いですが、上記のようなエラーが吐き出されます。



拡張子がjava以外のjavaソースコードをコンパイルしようとした場合


  • コンパイル(HelloWorld.txt)
 
C:\Java\HelloWorld>javac HelloWorld.txt
エラー: クラス名'HelloWorld.txt'が受け入れられるのは、注釈処理が明示的にリクエストされた場合のみです
エラー1個

C:\Java\HelloWorld>
 

これも注釈処理云々らしいです。
記事メニュー
ウィキ募集バナー