長い間メインで活用され人気のあるJavaをはじめよう!
Javaとは
1995年にSun Microsystemsからリリースされたプログラミング言語です。
現在はSun Microsystemsを買収したOracleが管理をしています。
オブジェクト指向プログラミングをサポートし、プラットフォームに依存しないため様々な環境で動作します。
プログラムの記述方法はC/C++から多くを引き継いでいます。
世界中の様々な現場で利用され人気の高いプログラミング言語です。
ちなみにAndroidのスマホアプリもJavaがメインの開発言語です。
また、子供に人気のゲームであるMinecraftもJavaで作られていたりと、いろいろなアプリやサービスでJavaを活用しています。
Javaの動作環境
基本的な開発環境はJava開発キット(Java Development Kit : JDK)を使って開発します。
JDKをインストールすれば実行環境が入っているのでJREを別途インストールする必要はありません。
プラットフォームにJava実行環境(Java Runtime Environment : JRE)が入っていればJavaは動作します。
ですがJava開発に必要なコンパイラやライブラリなどがないので、JDKをインストールしましょう。
JDKのインストール
ここでは本家であるOracle JDKのインストールを説明しますが、Java開発環境で使うおすすめのJDKはAdoptJDKです。以下の記事を参照ください。
https://codeaid.jp/jdk-change/
それではOracleの公式サイトからダウンロード します。
ここでは画面に表示されている最新版のインストールを例に説明します。
画面のJDK Downloadをクリックすると各プラットフォームのJDKを選択する画面に移動します。
JDKのライセンスは2019年4月16日のリリースより大きく変わっています。
ライセンスの変更によって、Oracleの公式サイトからダウンロードするJDKはサポートが有償化しています。
現在ではOracleJDKとOpenJDK/AdoptOpenJDKが存在します。
OpenJDKはGPL2ライセンスで配布されています。
OracleJDKもJavaを個人的に利用するには無償を継続しているので、学習目的でOracleJDKをインストールして利用するのは無償で行えます。
ただし、OracleJDKの最新ダウンロードはそのままできますが、古いバージョンについてはOracleのアカウントを作成する必要があります。
Linux、macOS、WindowsそれぞれのJDKを選んでダウンロードします。そして、画面上部に緑色の部分にライセンスに関する説明が書かれています。
Oracle JDKを使うにあたって内容を理解してくださいねということです。
各OSに対応したインストールファイルを画面右のファイル名をクリックしてダウンロードしてください。
Macへインストール
ダウンロードしたイメージファイルをダブルクリックでマウントするとpkgファイルが表示されます。
pkgファイルをダブルクリックしてインストールを実行してください。
あとは特に設定はなく画面の指示に従ってインストールを完了してください。
Macでは手動でシステム環境変数の設定も必要なくインストール直後からJavaが実行できます。
javaコマンドでバージョン確認してみましょう。
/usr/libexec/java_homeコマンドの実行でJavaの場所が表示され、java -versionコマンドでインストールしたJavaのバージョンが表示されれば完了です。
Windowsへインストール
ダウンロードしたインストールファイルを実行してインストールしてください。
Windows版も特にインストールでの設定はなく画面の指示に従ってインストールを完了してください。
インストールが完了したらWindowsの場合はシステム環境変数にJAVA_HOMEとPATHの設定をします。
Javaのシステム環境変数を設定(Windows)
Windowsの場合は、インストール後にJavaコマンドを使うためにPATH変数をシステム環境変数に設定する必要があります。
またアプリケーションによっては必要な、JAVA_HOME変数もシステム環境変数に設定します。
以下はWindows10で説明します。
Windowsメニューを右クリックして表示されるメニューから「システム」を選択
表示された画面の「バージョン情報」にある「システム情報」をクリック
「コンピューターの基本的な情報の表示」の「システムの詳細設定」をクリック
「システムのプロパティ」の「詳細設定」タブにある「環境変数」ボタンをクリック
まずはシステム環境変数にJAVA_HOME環境変数を作成します。
「環境変数」画面の下部にある「システム環境変数」の新規ボタンをクリックします。
「システム変数の編集」画面で変数名:JAVA_HOME、変数値:JDKのインストールパスを入力します。
インストールパスはJDKのインストールされた場所をエクスプローラーで開いてパス表示欄からコピペするといいでしょう。
次にPATHを設定します。
システム環境変数欄からPathを選択し、編集ボタンを押します。
環境変数の編集画面で新規ボタンを押して、「%JAVA_HOME%¥bin」を入力してエンターキーを押します。
これでPATHの設定は完了です。
Windowsを再起動して、シェルでjavaコマンドを使ってバージョン確認してみましょう。
java -versionコマンドでインストールしたJavaのバージョンが表示されればインストールは完了です。
Javaの実行
JavaはPythonのようにインタプリタ方式で動作するプログラミング言語ですが、C言語のようにコンパイルが必要です。
理由は、プラットフォームに依存することなく、且つより速く動作させるために考えられました。(詳しくは「コンパイルやインタプリタってなに? 」を参照ください。)
Javaでプログラムを書いたらjavacコマンドを使ってコンパイルします。
すると「.class」ファイルが生成されます。Javaで書いたプログラムを実行するには、このclassファイルを指定します。
例)Javaで書いたプログラムをSample.javaファイルに保存してプログラム実行する場合
Sample.javaをコンパイル
$ javac Sample.java
コンパイルすると、「Sample.class」というファイルが生成されます。これを実行するには、
$ java Samle
とコマンドを入力すれば実行します。(*指定するときに拡張子「.class」を省略します。)
JDK11からコンパイルせずとも他のスクリプト言語と同じようにjavaコマンドでソースコードを指定して実行できるようになっています。
ですがここではJavaの特徴としてコンパイルするがインタープリターで実行するところを説明します。
記述方法と特徴
Javaプログラムの記述方法はほぼC言語の記述方法を引き継いでいます。
・変数を定義する時はデータ型宣言をします。
int x;
・クラス、メソッド、制御文は{}で囲みます。
if (a == b) {
処理;
}
・コマンド文は;で終わります。
int x = 10;
System.out.println(x);
Javaはクラスベースのオブジェクト指向プログラミング言語です。すべてのプログラムはclassでまとめられています。
・classでまとめる
public class Sample {
public static void main(String[] args) {
処理内容;
}
}
このようなクラスが複数構成されてプログラムが動作します。
クラス内ではデータを定義し処理を記述します。この処理の部分をメソッドといいます。
メソッドの表記方法
修飾子 戻り値の型 関数名(引数型 引数名){ }
上記のSampleクラスにある「public static void main(String[] args)」がメソッドです。
修飾子: public, static
戻り値の型: void
関数名: main
引数: String[] args
このmainメソッドはアプリケーション実行の入り口となるメソッドで、プログラム本体に必ず記述するメソッドです。
この場合Sampleクラスで作ったアプリを実行すると最初に必ずmainメソッドが実行されます。
Javaプログラム
Javaはコンパイルするため、ソースコードはまずファイルに出力します。
なので、ここからはエディタを使ってプログラムを書いていきましょう。
まずはターミナルやコマンドプロンプトに「Hello World」を表示するプログラムを書いてみましょう。(*これを標準出力といいます。)
表示するための処理は「System.out.println()」というメソッドを使います。
これは引数で渡した値を標準出力するメソッドです。
System.out.println("Hello World");
Javaの文字列は全てダブルクォーテーション(“)で囲んで定義します。
これを先程のSampleクラスに書いてみましょう。
public class Sample {
public static void main (String[] args) {
System.out.println("Hello World");
}
}
エディタでプログラムが書けたら、Sample.javaというファイル名で保存します。
※保存するファイル名は必ずクラス名と同じでなくてはなりません。
またJavaは表記するクラス名・メソッド名・変数名(フィールド名)の全ては大文字と小文字が区別されます。(例:sampleとSampleは違う名前です)
今どきのエディタは初期値で文字コードの設定がUTF-8となっていますが、Windowsで使うエディタはShift-JISになっているものもあります。
UTF-8でファイル出力しないと動作しないプログラムもあるのでエディタの文字コード設定はUTF-8にしておきましょう。
Sample.javaファイルが作成できたら、このファイルをコンパイルします。
$ javac Sample.java
エラーなく終了できたら、そのフォルダにsample.classファイルが生成されています。
それがJavaアプリの本体です。それを実行してみましょう。
$ java Sample
実行するとコンソールに「Hello World」と表示されましたか?
Javaのクラス名・メソッド名・変数名(フィールド名)の表記方法はおおまかなルールがあります。
クラス名:パスカル記法(先頭は大文字、言葉の区切りは大文字)
例)Sample, Test, MainTask, NetAccess
メソッド名:キャメルケース記法(先頭は小文字、言葉の区切りは大文字)
例)checkStatus(), showCase(), addMemory()(処理内容とその対象を表す名前にすることが多いです)
変数名(フィールド名):全て小文字、言葉の区切りは大文字
例)count, errMsg
Javaも他の言語と同じようにコメント行を記述できます。
Javaのコメント行は「//」を記述します。複数行をコメントに指定することもできます。
その場合は「/*」と「*/」でコメントする部分を囲みます。
// コメント行
/*
複数行コメント
コメント1
コメント2
*/
パッケージ
Javaのソースファイル(.java)には複数のクラスを記述してもコンパイルできます。
コンパイルするとクラスごとに.classファイルが生成されます。
ですが基本的には、1ファイルに1クラスを記述します。
理由はいろいろあると思いますが、特に違うファイルに同じ名前のクラス定義があると衝突するため避けるためと、クラスの階層構造をより単純に分かりやすくするためかと思います。
世の中にはJavaのクラスファイルは多く出回り、ライブラリとして利用するケースも増えます。
プログラムの規模が大きくなりクラスが増えてくると、クラス名が衝突する確率も高くなり、クラスを整理する必要があります。
Javaはフォルダ階層と同じように、クラスを階層化するパッケージというのがあります。
Javaプログラムのほとんどはパッケージが定義されています。
パッケージ宣言されていないクラスはデフォルトパッケージとして取り扱われます。
package jp.hogehoge.sample;
public class Sample {
}
これはフォルダ(パッケージ)にファイル(クラス)があるイメージです。
上記の場合は「jp.hogehoge.sample」パッケージにSampleクラスがあるということになります。
通常はパッケージ名のフォルダにソースファイルを置きます。
./jp
|___hogehoge
|___sample
Sample.java
クラス名の衝突を避けるため通常はパッケージ名に所有しているインターネットドメイン名を逆さまにした名前を付けます。
インターネットドメインは唯一の名前だからです。
変数(フィールド)
Javaの変数は全てデータ型を指定して宣言します。
基本のデータ型には整数・浮動小数点数・文字・真偽値があります。
byte |
8bit(1byte) |
-128 ~ 127 |
short |
16bit(2byte) |
-32768 ~ 32767 |
int |
32bit(4byte) |
-2147483648 ~ 2147483647 |
long |
64bit(8byte) |
-9223372036854775808 ~ 9223372036854775807 |
float |
32bit |
約(-)3.40282347E+38 |
double |
64bit |
(-)1.79769313486231570E+388 |
char |
16bit |
\u0000 ~ \uFFFF *char型は1文字のUnicode文字を格納できます。 |
boolean |
1bit |
true、false |
またクラス型変数も使えます。これはクラスのインスタンスを格納する変数で、クラス名を宣言します。
String str = new String("Hello Japan");
変数にはメンバ変数とローカル変数があります。
メンバ変数はクラス直下に宣言し、クラスの他のメソッドからも参照できます。
ローカル変数はメソッド直下に宣言し、宣言したメソッド内でしか参照できません。
public class Sample {
int men = 5; // メンバ変数
String str = new String("Hello World");
public static void main (String[] args) {
int loc = 10; // ローカル変数
System.out.prontln(men);
System.out.prontln(loc);
System.out.println(str);
}
}
メンバ変数にはクラス変数とインスタンス変数があります。
クラス変数はnewによりインスタンスを作成しなくても参照できる変数です。
インスタンスに関係なく同じ変数を参照することになります。
「static」を付けて宣言します。
インスタンス変数はインスタンスを生成しないと参照できません。
public class Sample {
public static void main (String[] args) {
Test.num = 5; // インスタンスを生成する前に値を代入
Test testA = new Test();
System.out.println(testA.getValue()); // インスタンス生成前の値を表示
testA.num = 10; // testAインスタンスを使って値を変更
Test testB = new Test(); // 別のインスタンスを生成
testB.inst = "Normal"; // testBインスタンスを使って値を変更
System.out.println(testB.getValue()); // testBインスタンスを使っても同じ値が表示される
}
}
public class Test {
static int num; // クラス変数
String inst = "Initial"; // インスタンス変数
public String getValue() {
System.out.println(num);
System.out.println(inst);
String str = "Hello Test";
return str;
}
}
このサンプルの表示結果は以下です。
5
Initial
Hello Test
10
Change
Hello Test
変数に「private」修飾子を記述するとカプセル化することができます。
そうすると、そのクラス内でしか直接アクセスできない変数となります。
この場合、変数はクラス内だけでアクセスし、その値をセットしたり取得できるように関数を用意します。
public class Test {
private String inst; // インスタンス変数
public String getValue() {
return inst; // インスタンス変数instに設定された文字列を返す
}
public void setValue(String str) {
inst = str; // 引数で渡された文字列をセットする
}
}
演算子
変数に格納されている値を計算したり、期待通りの値かどうかを評価したり、メソッドの結果を評価するときに使われます。
加減算 |
“+”, “-“ |
乗算 |
“*” |
除算 |
“/” |
インクリメント |
“++” |
デクリメント |
“–“ |
剰余算 |
“%” |
等号 |
“==” |
不等号 |
“!=” |
比較 |
“>=”, “<=”, “>”, “<“ |
論理積 |
“&&” |
論理和 |
“||” |
否定 |
“!” |
用例と説明
【加減算、乗算、除算】
足し算”+”、引き算”-“、掛け算”*”、割り算”/”を行うときの演算子です。
a = 4 + 3; // aの結果は7です。
【剰余算】
割り算したときの余りを求める演算子”%”です。
a = 7 % 3; // aの結果は1(ture)です。
b = i % 3; // この例は、bの結果が0の場合はiは3で割り切れる値なので、iは3の倍数であることがわかります。
【インクリメント、デクリメント】
変数の値を1増加”++”したり、1減算”–“する演算子です。
変数の前に記述するのと後に記述するので意味が変わります。
a = ++i; // aの結果はiを1増加した値です。a = (i += 1);と同じです。
a = i++; // aの結果はiと同じです。aにiを代入したあとでiを1増加します。a = i; i = i + 1;と同じです。
【等号、不等号、比較】
値を比較するときの演算子です。
同じかどうか比較する場合は”==”、同じではないことを比較する場合は”!=”、大きさを比較する場合は”>=”, “<=”, “>”, “<“を使います。
条件文とともに使います。
if (x == y) // xとyが等しければ実行します。
if (x != y) // xとyが等しくなければ実行します。
比較の判定は「真偽値」で行います。
つまり「x == y」が成立するときは「真(true)」、そうでなければ「偽(false)」という値となります。
これはどのプログラミング言語でも必ず登場するので知っておきましょう。
関数の戻り値として型定義されていることも多く、プログラミング言語によっては「boolean型」として明確に型定義をします。
例えば、isActive(引数)といった関数があるとして、この関数では(引数)で渡されたものが有効かどうか?
を判定する処理を行い、戻り値として真(true)か偽(false)を返します。
関数ではこうやって利用されることが多いです。
if (x >= y) // xがy以上であれば実行します。
if (x < y) {
// xがyより小さいときに"Hello World"を表示します。
System.out.println("Hello World");
}
【論理積、論理和、否定】
これは条件をより簡潔に表現するのに使う演算子です。
なので条件文とともに使われます。
「〜かつ〜」であることを判定する場合は論理積” && “、「〜もしくは〜」であることを判定する場合は論理和”||”、「〜でない」ことを判定する場合は否定”!”を使います。
if ((x == 7) && (y == 3)) // xが7で、かつyが3であるときに実行します。
if ((x != 5) || (y == 10)) // xが5でないか、もしくはyが10のときに実行します。
if (!func()) // func処理の結果がfalse(偽)の場合に実行します。
true(真)とfalse(偽)は真偽値といって、ここでは処理結果が”1″ならばtrue(真)、”0″ならばfalse(偽)と理解しておくといいでしょう。
上記の例の場合だと、「func処理結果が”0″ならば実行する」ということになります。
「func処理結果が”1″である」ことを評価するには、if (func())と記述します。
つまり、否定”!”は真偽値を反転させて評価します。
配列
Javaで扱う配列は以下のように宣言します。
データ型[] 配列名;
例)
int[] numArray; // int型の配列をnumArrayという名前で宣言
String[] strArray; // String型の配列をstrArrayという名前で宣言
宣言した配列を使用する時は、配列を生成します。
numArray = new int[10];
strArray = new String[10];
また初期値を代入して宣言時に生成することもできます。
int[] numArray = {5, 10, 15, 20, 25};
String[] strArray = {"One", "Two", "Three", "Four", "Five"};
Javaの配列は生成後に配列の長さを変更することができません。
配列の各要素を扱うときは配列のインデックスを指定します。
numArray[2] = 20;
System.out.println(numArray[2]); // 20が表示されます。
System.out.println(strArray[1]); // "Two"が表示されます。
条件文
Javaの条件文はif文とswitch文があります。
if文
式には真偽値を判定する式を記述します。
この場合、結果がtrueの場合はif文内を処理し、falseの場合はelse文内を処理します。
if (式) {
処理内容;
} else {
処理内容;
}
複数のif文を記述することもできます。
if (式) {
処理内容;
} else if (式) {
処理内容;
} else {
処理内容;
}
例)
if (x == y) {
// xとyが同じなら処理を実行
}
また、3項演算式を書くこともできます。
式 ? 値 : 値;
例)
int x = 1;
String door = (x == 1 ? "開く" : "閉じる");
System.out.println(door);
switch文
式には整数(byte, short, int, long)の値だけが使えます。
合致したcaseの値があった場合はその処理内容を実行しbreakにてswitch文から抜け出します。
どのcaseの値にも当てはまらない場合は、default内の処理が実行されます。
switch (式) {
case 値:
処理内容;
break;
case 値:
処理内容;
break;
default:
処理内容;
break;
}
例)
switch (x) {
case 1:
// xが1の場合は処理を実行
break;
case 2:
// xが2の場合は処理を実行
break;
default:
// どのcaseにも当てはまらない場合処理を実行
break;
}
繰り返し文
Javaの繰り返し文はwhile文、do while文、for文があります。
while文
式には真偽値を判定する式を記述します。
結果がtrueの間はwhile文内の繰り返し処理を実行します。
while (式) {
処理内容;
}
例)
while (x == y) {
// xとyが同じ間は処理を繰り返し
}
do while文
do while文は一度でもdo文内の処理を実行したい場合に使用します。
式には真偽値を判定する式を記述します。
結果がtrueの場合再びdo文の処理を実行します。
do {
処理内容;
} while (式);
例)
do {
// 一度do文内の処理を実行し、xとyが同じ場合は再びdo文内の処理を実行
} while (x == y);
for文
for文内の処理を実行する前に初期化を行います。
そして条件がtrueの場合はfor文内の処理を実行します。
処理実行後に更新の記述内容を実行します。
そして再び条件の判定に戻り、trueの場合はfor文内の処理を実行します。
これを繰り返し、条件がfalseになればfor文を抜けます。
for (初期化; 条件; 更新) {
処理内容;
}
例)
for (int i = 0; i <= 100; i++) {
// 初期値として変数iを0をセットし、iが100より小さい場合for文内を処理し、iをインクリメントする
// iが100より小さい間は処理を繰り返す
}
FizzBuzz問題プログラム
FizzBuzzは海外の言葉遊びで、スタートして1から順に数字を発言していくのですが、3で割り切れる場合はFizz、5で割り切れる場合はBuzz、両方で割り切れる場合はFizzBuzzと発言します。
これをプログラミングしてみましょう。
プログラム全体の動作を以下のようにします。
- 1から順に100までカウントする
- 数える数字を1行ずつ画面に表示する
- 3で割り切れる数字のときは画面に「Fizz」を表示する
- 5で割り切れる数字のときは画面に「Buzz」を表示する
- 3と5で割り切れる数字のときは画面に「FizzBuzz」を表示する
for文を使って繰り返し処理を行うプログラムを考えてみましょう。
数字をカウントしながら、その数字を画面に表示するので、表示処理を100回繰り返すプログラムを記述します。
for (int i = 1; i < 101; i++) {
}
処理を100回繰り返すプログラムをfor文で書くとこのようになります。
- 「int i = 1;」でi変数を宣言し、初期値に1を代入 します。
- 「i < 101;」はi変数が101より小さい間処理をする条件となります。1から100まで数えるので、i変数が100のときも画面に表示します。
- 「i++」はfor文内の処理の最後に実行します。この場合は画面に表示したあとにiがインクリメントされます。
- System.out.println();関数でコンソール画面に表示します。
for (int i = 1; i < 101; i++) {
System.out.println(i);
}
次に、3で割り切れるときは「Fizz」、5で割り切れるときは「Buzz」、両方で割り切れるときは「FizzBuzz」、それ以外は数字を表示するようにプログラムを書きます。
if (i % 3 == 0 && i % 5 == 0) {
} else if (i % 5 == 0) {
} else if (i % 3 == 0) {
} else {
}
「%」は割り切れると「0」を返す演算子です。3と5で割り切れるかどうかを「==」で評価しています。各条件文にそれぞれの文字列を表示する関数を記述し、FizzBuzzクラスに定義します。
public class FizzBuzz {
public static void main (String[] args) {
for (int i = 1; i < 101; i++) {
if (i % 3 == 0 && i % 5 == 0) {
System.out.println("FizzBuzz");
} else if (i % 5 == 0) {
System.out.println("Buzz");
} else if (i % 3 == 0) {
System.out.println("Fizz");
} else {
System.out.println(i);
}
}
}
}
FizzBuzz.javaをコンパイルし、
javac FizzBuzz.java
作成されたFizzBuzz.classを実行します。
java FizzBuzz
実行するとコンソールに以下のように表示されましたか?
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
...
せっかくJavaプログラムを書いているので、クラスとメソッドを活用した記述方法に変更してみましょう。
for文内の処理を別のクラスとメソッドに分けて、for文内ではそのメソッドを呼び出して実行するように修正します。
分けたメソッドは引数で渡した値に合わせた”FIzz”、”Buzz”、”FizzBuzz”のいずれか文字列を返す機能を持ちます。
いずれも当てはまらない場合は数値を文字にして返します。
まずプログラムの本体は以下のようになります。
public class FizzBuzz {
public static void main (String[] args) {
Value val = new Value();
for (int i = 1; i < 101; i++) {
System.out.println(val.getValue(i));
}
}
}
次に、文字列を返すクラスとメソッドは以下のようになります。
3と5の倍数でない時は、数値を文字にして返さないといけないので、Integer.toString()関数を使って文字に変換して返しています。
public class Value {
public String getValue(int num) {
if (num % 3 == 0 && num % 5 == 0) {
return "FizzBuzz";
} else if (num % 5 == 0) {
return "Buzz";
} else if (num % 3 == 0) {
return "Fizz";
} else {
return Integer.toString(num);
}
}
}
このときFizzBuzz.javaをコンパイルしてできるクラスは、FizzBuzz.classとValue.classです。
実行して正しくコンソールに表示されたでしょうか。
プログラムはパズルを組み立てたり、なぞなぞを解いたりするのに感覚的に似ていませんか?
「はじめてのプログラミング」記事で少し触れましたが、パズルやなぞなぞが好きな人はプログラミングの習得が比較的速いかも知れません。
プログラミングは試行錯誤したあとに完成させることで達成感があります。
これをきっかけにJavaを学習してみてください。