S-JIS[2003-07-06/2024-03-22] 変更履歴

Java基礎知識・勉強方法

初めてJavaでプログラミングする人への参考に。[2008-08-20]

Javaに限った話ではないですが、新しくコンピューター言語を勉強する際は、まずはサンプルを入力して動かしてみましょう。[2010-06-20]
そしてちょっとソースを変えて実行してみて違いを見るのが重要です。

サンプルを入力する際は、一言一句変えないのが基本です。なぜなら、自分が知らないところで重要な違いがあるかもしれないからです。
大文字小文字の違い、ピリオドやセミコロンの有無・個数、果てはスペースや改行すら意味を持つことがあります。
(Javaでは大文字小文字が違うと別物扱いされる。スペースやタブ・改行には(行コメント文字列内を除いては)特に違いは無い)

  1. まずはJavaのインストール
  2. サンプルソースを書いてみる [/2010-06-20]
  3. コンパイルしてみる [/2010-06-20]
  4. 実行してみる
  5. パッケージ付きクラスのコンパイル・実行 [/2010-06-20]
  6. コンパイル先ディレクトリーの指定
  7. ここまでやってから高機能エディターを使う [/2010-06-20]
  8. 次に勉強すべき事 [2010-06-27]

Javaのインストール

Javaのコンパイルにはjavacコマンドを使う。これを使うためにはJDKをインストールする必要がある。
Javaの実行にはjavaコマンドを使う。これを使う為にはJRE又はJDKをインストールする必要がある。

JREはJDKに含まれているので、JDKをインストールすればよい。
JDKのインストール方法


コーディング

どこのディレクトリーでもいいので、ソースファイルを作成する。

下の例では、「C:\temp」というディレクトリーに「Example.java」というファイル名で作成している。 (ファイル名の大文字小文字も変えてはいけない)
中身はただのテキストエディターで書けば充分。

C:/temp/Example.java

/**
 * サンプル
 */
public class Example {

	public static void main(String[] args) {
		System.out.println("サンプルです");
	}
}

System.out.println()」は、コンソールに文字列を出力する方法。[2010-06-20]
ダブルクォーテーションで囲むと文字列になる。
文の末尾にはセミコロンが必要。

Javaでは常にクラスの中にプログラムを記述する。(C言語やJavaScriptのようなグローバル関数は無い)
クラス名とソースファイル名を一致させないといけないのが、Java特有の制約。


コンパイル

(Windowsの場合は、コマンドプロンプトを開いて)
ソースファイル「Example.java」を置いたディレクトリーに移動し、javacコマンドを使ってコンパイルする。

> cd C:\temp
C:\temp> javac Example.java

コンパイルが成功すれば、同じディレクトリー上に「Example.class」というファイルが作られる。

コンパイルして作られるファイルは直接実行できる実行ファイル(Windowsで言うexeやcom)ではない。[2010-06-20]
JavaのプログラムはJavaVM(仮想マシン)というプログラム上で実行されるので、いわばその為の中間ファイルが作られることになる。


実行

コンパイルしたファイル「Example.class」がある場所で以下のコマンドを打つと、実行される。

C:\temp> java Example
サンプルです

javaコマンドでは、引数にクラス名を指定するファイル名ではない。したがってExample.classを実行したい場合は「Example」を指定する)。
すると、そのクラスの中で「public static void main(String[] args)」というメソッドがあれば、そのメソッドが実行される。
もし無かったら実行されず、以下のようなエラーになる。

Exception in thread "main" java.lang.NoSuchMethodError: main

パッケージ付きクラスのサンプル

Javaでは、パッケージという、ディレクトリーに似た概念がある。
ファイルをサブディレクトリーに格納して整理するのと同様に、クラスを階層化した場所に置ける。
(本格的に作り出せばソースファイルの数が多くなるので、パッケージを使うのは必須。
 なお、パッケージ無しの場合は「デフォルトパッケージ」という扱いになる)

C:/temp/example/sub1/Example.java

package example.sub1;

/**
 * サンプル
 */
public class Example {

	public static void main(String[] args) {
		System.out.println("パッケージ付きサンプルです");
	}
}

パッケージ付きのクラスをコンパイルするには以下のようにする。

> cd C:\temp\example\sub1
C:\temp\example\sub1> javac Example.java

コンパイルが成功すれば、同じディレクトリー上に「Example.class」というファイルが作られる。

その他のコンパイル方法


パッケージ付きのクラスを実行するには以下のようにする。

> cd C:\temp
C:\temp> java example.sub1.Example
パッケージ付きサンプルです

パッケージ付きクラスの実行方法

javaコマンドでは、引数にクラス名を指定するファイル名ではない)。[2010-06-20]
パッケージexample.sub1に属するExampleクラスは、正式なクラス名(FQCN)は「example.sub1.Example」となるので、それを指定する必要がある。
(初心者がよくやる間違いが、「example.sub1.Example」と書かずに「Example」とだけ指定すること)

また、実行する場所も重要
上記の例で言えば、Example.classが置いてある場所で「java example.sub1.Example」を実行しても、上手くいかない。
なぜなら、javaコマンドは、カレントディレクトリー(厳密にはクラスパスで指定された場所)からクラスのファイルを探そうとする為。
example.sub1.Exampleというクラスのファイルは、「./example/sub1/Example.class」という場所にある想定となるので、そこに無いとエラーになる。

C:\temp\example\sub1> java Example
Exception in thread "main" java.lang.NoClassDefFoundError: Example (wrong name: example/sub1/Example)
C:\temp\example\sub1> java example.sub1.Example
Exception in thread "main" java.lang.NoClassDefFoundError: example/sub1/Example
Caused by: java.lang.ClassNotFoundException: example.sub1.Example

classesディレクトリー

上記のコンパイル方法の場合、ソースファイル(.java)とクラスファイル(.class)が同じ場所に置かれてしまう。
実行時に必要なのはクラスファイル群だけなので、クラスファイル専用の場所に置くのが望ましい。コンパイルオプション-dを使うことで、クラスファイルを置く場所を指定できる。

以下の例では、「C:\temp\src」の下にソースファイルを格納している前提で、「C:\temp\classes」にクラスファイルを作成する。

> cd C:\temp\src\example\sub1
C:\temp\src\example\sub1> javac -d C:\temp\classes Example.java

実行は以下のようにする。

> cd C:\temp\classes
C:\temp\classes> java example.sub1.Example
パッケージ付きサンプルです
> java -classpath C:\temp\classes example.sub1.Example
パッケージ付きサンプルです

高機能エディター

実際にJavaで開発するには、Eclipse等の統合エディター(IDE)を使用するのが断然楽。

しかしそれらのIDEでも、やっていることは上記のようなコンパイル・実行である。

また、実際の業務でJavaプログラムを実行する場合、Eclipseから実行するなどという事は有り得ない。[2010-06-20]
パッケージ付きクラスの実行方法を覚えておくことは必須だ。


次に勉強するもの

Javaで何か作ろうと思ったら、作りたい物(使用するクラス)に関連して勉強しておいた方がいい文法があるかも。[2010-06-27]

項目 概要 関連して勉強すべき文法
Javaで使える基本的なデータ型。  
Javaで使える演算子。  
Javaの文(ステートメント)。  
コレクション Javaでは、リストやマップ(連想配列)といったアルゴリズムに関するクラスが標準ライブラリーとして用意されている。
よく使うのでぜひ知っておくべき。
インターフェース(interface)
ジェネリクス(<T>)
ファイル入出力 コンソールへの出力の次は、ファイルとの入出力が基本かと思われる。
(コンソールからの入力は、自分は使ったこと無い^^;)
インターフェース(interface)
例外補足(try〜catch
クローズの作法(try〜finally
ウィンドウアプリ クライアントPCでウィンドウを開いて操作する(GUI)アプリケーションは、Javaではあまり作られないが…。
SwingSWT(とかJavaFX)など。
 
ウェブアプリ インターネット(ブラウザー)からのリクエストを処理するサーバー側のJavaアプリケーション。
サーブレットJSPが基本だが、フレームワーク(Strutsが有名)で隠蔽されることがほとんど。
 
アプレット ブラウザー上で稼動するクライアント側のJavaアプリケーション。
最近はあまり見かけないが、当初Javaは、この機能が一番注目されていた。
 
DBアクセス Javaでは、RDBへのアクセスにはJDBCを使用する。
が、大抵は何らかのフレームワークを使うので、直接JDBCを扱うことはまず無い。
 
JUnit Javaでの単体テスト技法。 staticインポート
アノテーション(@)

その他、アパッチソフトウェア財団が提供しているプロダクトやライブラリーもよく使われる。

ほとんどのライブラリー(クラス)の説明はJavadocという形で提供されているので、“まずはそれを見る”という癖を付けよう。


Javadocの見方

Javaの標準ライブラリー(API・クラス群)の説明は、HTMLで見る事が出来る。→SunのAPI仕様 …これがネット上で公開されているというのが、Javaでプログラミングしやすい要因の一つだと思う。
ここでどんなクラス・メソッドがあるのか調べるのが、基本中の基本。
(これらはJavadocという文法で作られており、自分でも簡単に作ることが出来る。→Javadocの書き方

そのクラスがどこで使われているかという情報も、フレーム上部の「使用」というリンクをクリックすることで見ることが出来る。
また、継承関係もフレーム上部の「階層ツリー」リンクをクリックすれば見ることが出来る。

ただ、独特の用語(訳語)が使われている部分もあり、慣れないと疑問に思う単語もある。


ジェネリクス(総称型)はJDK1.5で導入されたものだが、これは初心者が読みこなすのは難しい面もあり、評判があまり良くない。個人的にはけっこう大好きな文法なのだが、確かにややこしい奴は難しい。

Javadocを見ていて「class クラス名<E>」という形で出てきたら、ひとまずそれは無視して「class クラス名」というクラス宣言だと思えばいい。
その後「E getValue()」とか「void setValue(E arg)」というメソッドが出てきたら、それは「Object」が指定されているものと思っていい。
つまり「Object getValue()」とか「void setValue(Object arg)」と同じ。
使う際も「クラス名 obj = new クラス名();」「Object r = obj.getValue();」という形で使える。

実際には型引数Eにはプログラマーがクラスを指定できるのだが、それはジェネリクスを勉強のこと。
「クラス名 obj = new クラス名<String>();」「String r = obj.getValue();」という感じ。
とりあえずListクラスを色々試してみるのがいいと思う。


ソースファイル

Javaでは、ソースのファイル名ソース内のメイン(ソース内でpublicの付いているクラス)のクラス名とを一致させる必要がある。[2003-07-06]
クラス名は大文字小文字を区別するので、ファイル名も大文字小文字は区別する必要がある。

また、publicの付いたクラスを1つのソースで2つ以上記述することは出来ない。
(publicの付いていないクラスなら、いくつ書いてもよい。publicの付いたクラスが1つも無くてもOK)[2007-06-20]
(厳密には、クラスだけでなく、インターフェース列挙アノテーション定義を含めて、最大1つだけpublicを指定できる

ソースファイルの拡張子はjava。(コンパイル後のバイトコードのファイルの拡張子はclass)
ソース内に複数のクラス(やインターフェース等)が書かれている場合、クラスの数だけclassファイルが作られる。
内部クラス無名クラスも個別のclassファイルが作られる。

Javaではソースは基本的にUnicode(UTF-16)で書くことになっている(Java言語仕様3.1章)が、SJISでも書ける。
厳密には、ソースの中の文字列(コメントも含む)でSJISを使っている場合は、javacでコンパイルする際にオプション「-encoding MS932」を指定して SJISを使っていることを明示する。
(という事になっているようだが、実際には(普通の環境では)指定しなくても大丈夫)

ソース内の改行はCRLFでもLFでもCRでもOK(Java言語仕様3.4章)。[2008-09-13]
Windows(MS-DOS)ではテキストファイルの終わり(EOF)として0x1aが付いていることがあるが、(ファイルの最後であれば)これは無視される(Java言語仕様3.5章)。

コンパイルした後、内部の動作時には全てUnicodeで扱われる。画面に表示するとき等は、自動的にクライアントの環境に合わせて変換して表示される。


コメント

「/*」「*/」で囲むか、行頭が「//」であれば、コメントとして扱われる(Java言語仕様3.7章)。[2008-09-13]

「/*〜*/」は「従来からのコメント(TraditionalComment)」というのが正式な呼び名らしい。
確かにC言語やPL/Iでも使われていた伝統的な形式だが…もうちょっと固有名詞っぽい名前は無いのか^^;
(この形式のコメントはネストできない)
(「/**〜*/」はJavadocコメントと呼ばれる。Javadocを生成しないなら普通のコメントと同じ)

「//」は素直に「一行コメント(EndOfLineComment)」。


文字列中にコメント記号を入れても それはコメント扱いにはならない。

	String str1 = "/*文字列*/";
	String str2 = "//文字列";

識別子の名前に関する慣例

Javaにおける識別子(クラス名・変数名やメソッド名)の命名の慣例。[2003-07-06]

インターフェース名の先頭に「I」とかを付けるのは、C#なんかじゃありそうだけどJavaではやらない。[2007-12-21]
インターフェースの実装クラスの名前の末尾に「Impl」を付けるのは、昔の規約にそんな記述があったそうだが、はっきり言って変。
複数のインターフェースを実装する場合や1つのインターフェースに複数の実装がある場合はどーするんだ。
逆に言えば、唯一の実装しか無い場合はImpl付けちゃうのが(考える必要が無くて)楽だけど。

妙:「$」も使えるが、使うべきではない


単一アンダースコア

JDK1.8では、単一のアンダースコア「_」を識別子に使うと警告が出るようになった。[2014-03-20]

class _ {

	void _() {
		int _ = 1;
		System.out.println(_);
	}
}

javacだと「警告: 識別子として'_'が使用されました (識別子としての'_'の使用は、Java SE 8より後のリリースではサポートされない可能性があります)」という警告が出る。
Eclipseだと「'_' should not be used as an identifier, since it is a reserved keyword from source level 1.8 on」という警告メッセージが出る。

なお、ラムダ式の引数の変数名に単一アンダースコアを使おうとするとコンパイルエラーになる。
javacだと「エラー: '_'が識別子として使用されています (ラムダ・パラメータでは'_'を識別子として使用することは禁止されています)」というエラー。


Java9では単一アンダースコア「_」はキーワードになった。使用するとコンパイルエラーになる。[2017-09-23]

> javac Underscore.java
Underscore.java:2: エラー: リリース9から'_'はキーワードなので識別子として使用することはできません
class _ {
      ^
Underscore.java:3: エラー: リリース9から'_'はキーワードなので識別子として使用することはできません
        void _() {
             ^
Underscore.java:4: エラー: リリース9から'_'はキーワードなので識別子として使用することはできません
                int _ = 1;
                    ^
Underscore.java:5: エラー: リリース9から'_'はキーワードなので識別子として使用することはできません
                System.out.println(_);
                                   ^
エラー4個

Java22で「_」は無名変数として扱われるようになった。[2024-03-22]
すなわち、使用しない変数に「_」が指定できるようになった。


Java目次へ戻る / 新機能へ戻る / 技術メモへ戻る
メールの送信先:ひしだま