iOSからAndroidの開発に移行するにあたってJavaが初めてだったので、その際学習した時のメモを残しておきます。
1.Javaの概要
1.1 Javaとは
Javaとは1995年にサン・マイクロシステムズ社が開発した、オブジェクト指向のプログラミング言語である。単にJavaといった場合、こうしたプログラミング言語としてのJavaだけでなく、Javaライブラリや開発環境を含めたプラットフォーム全体の総称を意味することもある。以後は単にJavaと記載した場合、プログラミング言語としてのJavaを意味するものとする。
Javaは以下のような特徴を持つプログラミング言語である。
- 構文はCおよびC++から多くを引き継いでいる。
- オブジェクト指向プログラミングをサポートしている。
- 機械語に直接コンパイルされるのではなく、中間言語(Javaバイトコード)にコンパイルされ、Java仮想マシン(Java Virtual Machine、JVM)と呼ばれる仮想マシン上で動作する。これにより、Java言語で作成されたプログラムはJava仮想マシンが動くOSであればどのようなOS上でも動作する。
- Javaで作成されるソフトウェアには、Webブラウザー上で動作するJavaアプレットと、単体で動作するJavaアプリケーションの2種類がある。また、Webサーバー側でJavaプログラムを実行するJava EE(Java Platform, Enterprise Edition)は、動的なページの生成やWebアプリケーションの構築に広く使われている。
1.2 Javaの各バージョンのキーワード
バージョン | キーワード |
---|---|
Java5 | ジェネリクス、オートボクシング・アンボクシング、enum型、アノテーション、拡張for文、Concurrency Utilities |
Java6 | AWT・Swingの高速化、JDBC4.0、性能改善、Concurrency Utilitiesの強化 |
Java7 | NIO2、Fork/Join フレームワーク、try-with-resources、ダイアモンド記法、例外のマルチキャッチ |
Java8 | ラムダ記法、メソッド参照、Stream API、インターフェースのデフォルトメソッド、新Time API |
1.3 JDK、JREについて
JRE(Java Runtime Environment)とはJava実行環境、すなわちJavaで作られたプログラムを実行するために必要な環境一式のことである。JREはJava仮想マシン(JVM)と標準のJavaクラスライブラリのセットであるAPI(Application Programming Interface)から成り立っている。
一方、JDK(Java Development Kit)とはJavaの開発環境のことである。JDKは各OS上でのJava開発者向けのバイナリでありオラクルにより公開されている。JDKはJREを含んでおり、Javaを開発する上で必要な環境を提供する。
2.Javaの基礎
2.1 Javaの変数と型
Javaの型はprimitive type(プリミティブ型)とreference type(参照型)に大別される。プリミティブ型に属する型には以下の8種類が存在する。
型名 | 解説 | 値 | デフォルト値 |
---|---|---|---|
boolean | 真偽値 | true, false | false |
byte | 8ビット整数 | -128〜127 | (byte)0 |
short | 16ビット整数 | -32768〜32767 | (short)0 |
int | 32ビット整数 | -2147483648〜2147483647 | 0 |
long | 64ビット整数 | -9223372036854775808L〜9223372036854775807L | 0L
char | UTF-16のコードポイント | 'a'、'あ'、'言'、'\u03b1'など | '\u0000' (null文字)
float | 32ビット浮動小数点数 | 1.54fなど | 0.0f
double | 64ビット浮動小数点数 | 2.45dなど | 0.0d
参照型には大別してクラス型、インターフェース型、型パラメータ、配列型の4種類がある。それぞれについては別途記載。
2.2 リテラル
リテラルとはプリミティブ型の値、文字列、null値をコード場で記述する際の表現方法のことである。それぞれの型のリテラルを以下に示す。
リテラルの種類 | 生成される値の型 | 記述方法 | 例 |
---|---|---|---|
整数(10進数) | int | 数字を列挙する | 128 |
整数(16進数) | int | 数値の先頭に0xまたは0Xをつける | 0xab
整数(8進数) | int | 数値の先頭に0をつける | 012
整数(2進数) | int | 数値の先頭に0bまたは0Bをつける | 0b11
整数 | long | 整数値の最後にlまたはLをつける | 123L
浮動小数点数 | float | 小数の最後にfまたはFをつける | 2.34f
浮動小数点数 | double | 小数または指数表現 | 3.45、345e<sup>-2</sup>
文字 | char | シングルクォーテーションで文字を囲む | 'a'
文字列 | String | ダブルクォーテーションで文字列を囲む | "abc"
真偽値 | boolean | true, false | true
null値 | null型 | null | null
2.3 演算子
基本はC言語と同じ演算子なので、あまり使わないであろうビット演算子の一部のみ記載する。
演算子 | 例 | 解説 |
---|---|---|
>> | a>>1 | aを右に1ビットシフトする。左端は最上位ビットと同じ値で埋める |
>>> | a>>>1 | aを右に1ビットシフトする。左端は0で埋める |
~ | ~a | aの全てのビットを反転させる |
2.4 コメント
コメントはC言語と同じく、// 一行コメント、もしくは /* ブロックコメント */で記載する。基本的にはJavadoc形式でのコメントが望ましい。
2.5 分岐
基本的に条件分岐はC言語と同様のため、詳細は割愛するが、何点かの注意事項のみ記載する。
- switch文にて値がnullの場合、NullPointerExceptionが投げられる。
- for文には拡張for文と通常のfor文がある。Java 8であればStreamが使えるため、そちらを使うことが多い。
2.6 例外処理
【例外について】
Javaにおける例外には以下の3種類があり、いずれもThrowableクラスを継承したクラスで表現される。
- 検査例外(Exception):プログラム中で必ず対処が必要な例外。例外をさらに上の呼び出し元に投げるか、try-catch構文で例外をcatchする必要がある。
- 実行時例外(RuntimeException):プログラム中で対処が必要ない例外。主にプログラム作成時には想定されていないエラーを通知するために使用する。
- エラー(Error):プログラムで対処しない例外。リソース不足が原因で処理を続行できないなど、動作を継続できない致命的なエラーを示すことが多い。
【例外の投げ方】
例外を発生させることを例外を投げるということが多い。Javaでは「throw new 例外クラス()」で例外を投げることができる。検査例外を投げる場合、Javadocに@throwsを使ってどういう状況でその例外が投げられるのかを記載しておくのが望ましい。よく使われる実行時例外としては以下のものがある。
例外 | 投げるケース |
---|---|
IllegalArgumentException | 呼び出し時の引数の値が不正である場合 |
IllegalStateException | オブジェクトの状態が不正の時にメソッド呼び出しされた場合
NullPointerException | nullが禁止されている引数にnullが渡された場合
IndexOutOfBoundsException | インデックスを指定するような引数に範囲外の値が指定された場合
2.7 リソース
ファイルのオープンやDB接続、ネットワーク接続等のリソースを用いる処理を使う場合、try-with-resources構文を使用する。リソースを閉じる処理はブロックを抜けるタイミングで自動的に実行され、ブロック内で例外が発生した場合でもリソースを閉じる処理は実行される。なお、リソースを閉じる処理の途中で例外が発生する場合は、最後にcatch説を付け加えることでその例外に対するハンドラを書くことができる。
try (クラス名 変数名 = リソースの取得) {
リソースを使った処理
}
2.8 修飾子
クラス、インタフェース、メソッド、コンストラクタ、変数には、下記の 修飾子 を指定することができる。
修飾子 | class | interface | method | constructor | block | var | 分類 | 説明 |
---|---|---|---|---|---|---|---|---|
public | ○ | ○ | ○ | ○ | × | ○ | アクセス修飾子 | 全クラスからアクセス可能 |
[protected](http://www.tohoho-web.com/java/modifier.htm#access) | ○ | ○ | ○ | ○ | × | ○ | アクセス修飾子 | <span style="color: rgb(0,0,0);">他ファイル・他クラスからのアクセスをプロテクト</span>
[private](http://www.tohoho-web.com/java/modifier.htm#access) | ○ | ○ | ○ | ○ | × | ○ | アクセス修飾子 | 自クラスからのアクセスのみ
[static](http://www.tohoho-web.com/java/modifier.htm#access) | ○ | ○ | ○ | × | × | ○ | static修飾子 | <span style="color: rgb(0,0,0);">インスタンス化されていなくても、参照可能であることを示す</span>
[final](http://www.tohoho-web.com/java/modifier.htm#final) | ○ | × | ○ | × | × | ○ | final修飾子 | 上書きされないことを示す。継承、overload、変更の禁止の意
[abstract](http://www.tohoho-web.com/java/modifier.htm#abstract) | ○ | ○ | ○ | × | × | × | 抽象修飾子 | <span style="color: rgb(0,0,0);">抽象的なもので、中身は継承先で定義・実装することを示す</span>
[native](http://www.tohoho-web.com/java/modifier.htm#native) | × | × | ○ | × | × | × | native修飾子 | <span style="color: rgb(34,24,21);">Java以外の言語で実装されていることを示す</span>
[synchronized](http://www.tohoho-web.com/java/modifier.htm#synchronized) | × | × | ○ | × | ○ | × | 同期修飾子 | <span style="color: rgb(0,0,0);">マルチスレッドの場合、排他制御が行われることを示す</span>
[transient](http://www.tohoho-web.com/java/modifier.htm#transient) | × | × | × | × | × | ○ | 一時的修飾子 | シリアライズ対象外であることを示す
[volatile](http://www.tohoho-web.com/java/modifier.htm#volatile) | × | × | × | × | × | ○ | 揮発性修飾子 | <span style="color: rgb(34,24,21);">キャッシュを抑制し、スレッド間で値が同じになることを示す</span>
[strictfp](http://www.tohoho-web.com/java/modifier.htm#strictfp) | ○ | ○ | ○ | × | × | × | 厳密浮動小数修飾子 | <span style="color: rgb(0,0,0);">浮動小数点演算がプラットフォームに依存せず、厳密に動作する</span> |
2.9 アノテーション
【アノテーションについて】
アノテーション とは「注釈」を意味し、クラスやメソッド、パッケージに対して付加情報を記入する機能である。Java SE 5で追加され、「@ + アノテーション名」という形式で使用する。
アノテーションには以下のようなアノテーションが存在する。
- マーカーアノテーション:データがなく、名前だけを持つアノテーション(@Override、@Duplicateなど)
- 単一値アノテーション:データを一つだけ持つアノテーション(@SuppressWarningsなど)
- フルアノテーション:複数のデータを持つアノテーション
- メタアノテーション:アノテーションに付与するアノテーション
以下に標準で提供されているアノテーションについて例を挙げて解説する。
- @Deprecated:そのメソッドの仕様が非推奨であることを明示的にするアノテーション。警告メッセージがコンパイル時に表示されるようになる。
- @Override:スーパークラスで定義されているメソッドをオーバーライドする際に使用するアノテーション。引数などが異なる際にコンパイルエラーになる。
- @SuppressWarnings:コンパイラが出す警告を抑制するアノテーション。引数のメッセージによってコンパイル時のエラーを非表示にすることができる。
- @SafeVararg:可変長引数を持つメソッドをコンパイルした際の警告を抑制するアノテーション。ジェネリクスにおいてClassCastExceptionを投げる可能性があるため警告が出るが、 その可能性がない場合に利用する。
- @FunctionalInterface:関数型インターフェースを定義するクラスやインターフェース、enumに使われるアノテーション。
【アノテーションの作成方法】
import java.lang.annotation.*;
// 定義しているアノテーションの情報をどこまで保存するかの指定(RUNTIMEで実行時にも情報を保持する)
@Retention(RetentionPolicy.RUNTIME)
// 定義しているアノテーションをコード場のどの箇所につけるのかの指定。TYPEでクラス、インターフェース、enumに記述できることになる。
@Target(ElementType.TYPE)
// 定義しているアノテーションの情報がJavadocにも記載されるようになる。
@Documented
public @interface Beta {
String from(); // fromと言う名前の文字列型の引数をとることができる。@Beta(from = "1.0");などと記述する。引数名がvalueで、それのみならvalueと言う記述は省略可
}
2.10 関数型インターフェースとラムダ式
【関数型インターフェース】
メソッド名とシグネチャ、戻り値の型の宣言だけを行うメソッドのことを抽象メソッド(abstract method)と呼び、以下のような形式で記述する。
abstract [戻り値型] <メソッド名>(シグネチャ);
この抽象メソッドと定数、defaultメソッド、staticメソッドをメンバーに持つことができるものをインターフェース(interface)と呼び、以下のような形式で記述する。
[修飾子] interface <インタフェース名> {
データ型 変数名 = 値;
修飾子 戻り値のデータ型 メソッド名(引数の型宣言);
}
関数型インターフェース(functional interface)とは定義されている抽象メソッドが一つだけであるようなインターフェースのことである。なお、defaultメソッドやstaticメソッドを含んでいる場合でも抽象メソッドが一つだけであれば関数型インターフェースに含まれる。
【ラムダ式】
ラムダ式とはJava SE 8で導入された構文であり、関数型インターフェースの実装を簡潔に記述できる構文である。関数型インターフェースを引数とするメソッド呼び出しにおいて、ラムダ式は該当の関数型インターフェースの引数箇所に使用することができ、以下のように記述する。
(ラムダ式の引数) -> { 処理 }
参考URL:http://www.ne.jp/asahi/hishidama/home/tech/java/lambda.html
2.11 メソッド参照
メソッド参照はJava SE 8で導入された構文であり、関数型インターフェースの変数にメソッドそのものを代入することが出来る構文である。メソッド参照は以下のようにして指定する。
// staticメソッドの場合(場合によってはインスタンスメソッドも)
クラス名::メソッド名
// インスタンスメソッドの場合
インスタンス変数名::メソッド名
2.12 Optionalクラス
OptionalはJava SE 8で導入されたクラスであり、値を1つラップするだけのクラスである。Optionalはただ単に値を保持しているだけだが、Optionalの各メソッドは保持している値がnullか否かによって挙動が変わる。(基本的に、null以外のときだけ処理が行われる)
Optionalのインスタンスは、内包している値がnullの場合はemptyというオブジェクトになり、値が有る場合は普通に値を保持するインスタンスとなる。Optionalを受け取った側は、そのOptionalがemptyかどうかを判定して処理を行う。Optionalにnullが入っているかどうかの判定にはisPresentメソッドを使用する。また、isPresent以外にも値が格納されていない場合に指定した値を返すorElse、値が格納されていない場合に例外を投げるorElseThrowなどがある。