Oracle Certified Java Programmer, Silver SE 11 認定資格の学習ログ
第1章 簡単なJavaプログラムの作成
パッケージに関する問題
パッケージの目的は3つ
- 名前空間を提供し、名前の衝突を避ける
- 名前空間:
- あるものの「名前」を付ける際に、その名前が別のものの「名前」と同じ場合、名前だけでは「どちらなのか」が分からないため、このような場合には名前を付けることができない。
- 慣習でドメイン名を逆にした文字列をパッケージ名に利用
- 完全修飾クラス名:
- パッケージ名.クラス名
(例:java.util.ArrayList)※util:ユーティリティのことで、「役に立つもの」
- パッケージ名.クラス名
- アクセス修飾子と組み合わせてアクセス制御機能を提供する
- パッケージ単位でアクセス制御が可能
// jp.co.xxxパッケージに属するpublicなSampleクラスの宣言
packege jp.co.xxx;
public class Sample {
// any code
}
// jp.co.xxxパッケージに属するTestクラスの宣言
packege jp.co.xxx;
class Test { // publicで宣言していない→外部のパッケージからアクセス不可
// any code
}
アクセス修飾子 | 同一クラス | 同一パッケージ | サブクラス | すべて※ |
---|---|---|---|---|
public | ○ | ○ | ○ | ○ |
protected | ○ | ○ | ○ | × |
デフォルト | ○ | ○ | × | × |
private | ○ | × | × | × |
※すべて=他のパッケージを含む | ||||
- クラスの分類を可能にする
- パッケージはディレクトリ構造とマッピングされます。
- 例:jp.co.xxx.Sampleという完全修飾クラス名を持つクラス
jp/
├ co/
├ xxx/
├ Sample.class
パッケージ宣言に関するルールを覚える。
- 必ずソースコードの先頭行に記述
- 宣言より前に記述できるのはコメントのみ
// jp.co.xxxパッケージに属するpublicなSampleクラスの宣言
packege jp.co.xxx;
import java.io.*;
public class Sample {
// any code
}
クラスのインポートに関する問題
コンパイラやJVMはクラスを完全修飾クラス名でしか扱えない。
パッケージ宣言しなかったら、無名パッケージに所属。
//完全修飾クラス名でクラスを指定したソースコード
package hoge;
public class Sample {
public static void main(String[] args) {
java.lang.String str = "100";
int val = java.lang.Integer.parseInt(str);
java.math.BigDecimal decimal = new java.math.BigDecimal(val);
System.out.println(decimal.intValue());
}
}
インポート宣言をするだけで、パッケージ名を省略してクラス名だけで記述可。
//クラスのパッケージ名を省略するため、インポート宣言をしたソースコード
package 黒本;
import java.lang.String; //省略可能
import java.lang.Integer; //省略可能
import java.math.BigDecimal;
public class Sample {
public static void main(String[] args) {
String str = "100";
int val = Integer.parseInt(str);
BigDecimal decimal = new BigDecimal(val);
System.out.println(decimal.intValue());
}
}
アスタリスクを利用してそのパッケージに属するクラスを全てインポート可。
// java.utilパッケージに属する全クラスのインポート宣言
import java.util.*;
インポートの範囲は指定したパッケージに属するクラスに限定されるので、サブクラスは不可。
パッケージとクラスのアクセス制御
パッケージ宣言したクラスから、無名パッケージに属するクラスにアクセス:コンパイルエラー
無名パッケージに属するクラスは、同じ無名パッケージに属するクラスからしかアクセスできない。
mainメソッドに関する問題
処理を始めるためのメソッド=エントリーポイント
//エントリーポイントとなるメソッドの定義(mainメソッド)
public class Sample {
public static void main(String[] args) {
// any code
}
}
- 公開されていること(public)
- インスタンスを生成しなくても実行できること(static)
- 戻り値は戻せない(void)
- メソッド名はmainであること
- 引数はString配列型を1つ受け取ること
- 可変長引数のString型も可(String... args)※コンパイル時に変換される
Javaコマンドの実行に関する問題
javaコマンド=JVMを起動するためのコマンド(以下、構文)
引数=「起動パラメーター」や「コマンドライン引数」と呼ぶ
配列型変数argsで参照できる(args[0] = 引数1)
■実行の動作
- javaコマンドを実行
- JVMを起動する
- 指定されたクラスをクラスパスから探し出してロード
- String配列型オブジェクトを作成し、起動パラメーターを格納
- 起動パラメーターを保持したString配列型オブジェクトへの参照を引数に渡してmainメソッドを実行
起動パラメーターに関する問題
> java Sample a " a" "a "b c
n番目 | 引数 | 解説 |
---|---|---|
1 | a | |
2 | " | エスケープされた引用符がそのまま引数として渡される |
3 | a" | エスケープされていない引用符がそのまま文字列の一部として渡される |
4 | a b | ダブルクオート内の文字列は一つの引数として扱われる |
5 | c |
上記をlengthで確認すると「5」と表示される。
配列は0からカウントしないのか?
個々の要素にアクセスする場合は0から始まるインデックスを使用します。
しかし、length自体は要素の「数」を示しているため、5となります。
第2章 Javaの基本データ型と文字列操作
基本データ型(プリミティブ型)に関する問題
データ型 | 値 |
---|---|
boolean | true or false |
char | 16ビットUnicode文字 \u0000~\uFFFF |
byte | 8ビット整数 -128~127 |
short | 16ビット整数 -32,768~32,767 |
int | 32ビット整数 -2,147,483,648~2,147,483,647 |
long | 64ビット整数 -9,223,372,036,854,775,808~9,223,372,036,854,775,807 |
float | 32ビット単精度浮動小数点数 |
double | 64ビット倍精度浮動小数点数 |
整数リテラルに関する問題
Javaでは数値を10進数のほかに、2進数、8進数、16進数のリテラルで表記可。
n進数 | 接頭辞 |
---|---|
2 進数 | 先頭に「0b」 |
8 進数 | 先頭に「0」 |
16 進数 | 先頭に「0x」 |
n進数 | 数値や文字 |
---|---|
2 進数 | 0, 1 |
8 進数 | 0, 1, 2, 3, 4, 5, 6, 7 |
16 進数 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F |
16進数の「A」は10、「B」は11、「C」は12、「D」は13、「E」は14、「F」は15を表す。 |
Java SE 7から導入された「アンダースコア」(_)=桁数の多い数値を見やすくする。
- リテラルの先頭と末尾には記述しない
- 記号の前後には記述できない
- 記号:「 . 」「 L (Long型)」「 F (Float型) 」「 0b 」「 0x 」
文字リテラルと文字列リテラルの違いに関する問題
- 文字リテラル:「'a'」(シングルクォーテーション)
- 文字列リテラル:「"a"」(ダブルクォーテーション)
char型=文字リテラルのみ代入可
ダブルクォーテーション不可
nullも不可(参照型変数が「何も参照しない」ことを表現するデータ)
char型の変数:0~65535までの数値を代入可
識別子の命名規則に関する問題
Javaでは変数やメソッド、クラスのことを「識別子」と呼ぶ
- 予約語を識別子として使うことはできない
- 使用できる記号はアンダースコア「 _ 」と通貨記号「 $ 」のみ
- 先頭に数字の使用はNG
varを使った変数宣言に関する問題
変数宣言時のデータ型を推論する機能(型推論)が追加
var a = 10;
コンパイル時にコンパイラが代入演算子「=」の右辺から変数のデータ型を推論し、
データの型に置き換える機能
■使えない
- 変数が初期化されていない( var a; )
- nullで初期化する( var a = null; )
- 複数の変数を宣言( var a = 10, b = 20; )
- ラムダ式のみ( var a = () -> {}; )※何のインターフェースを実装しているのか不明
- 配列の初期化式( var a = {1, 2, 3}; )
- (正:var a = new int[]{1, 2, 3}; )※仕様でサポートされてない
- フィールド宣言(メンバ変数:クラス直下(メソッドの外側)に書かれた変数)
- 引数の型宣言時
ダイヤモンド演算子(<>)ではObject型が使われる
var a = new ArrayList<>();
↓
var a = new ArrayList<Object>();
ローカル変数の初期化時も使用可能(メソッド内に書かれた変数のこと。)
public class Sample {
public static void main(String[] args) {
var a = 100; // ローカル変数なのでvarを使用できる
}
}
Stringオブジェクトの作成に関する問題
Stringクラスのインスタンスを生成する方法
- newを使う(String a = new String("sample"); )
- ダブルクオーテーションの文字列リテラル(String a = "sample"; )
- String型特有
- valueOfメソッド(String a = String.valueOf("sample"); )
StringクラスのchartAtメソッドに関する問題
String str = "abcde";
System.out.println(str.chartAt(4)); //e
範囲外を指定すると「例外発生」
StringクラスのindexOfメソッドに関する問題
String str = "abcde";
System.out.println(str.indexOf("cd")); //2:文字列が始まる最初の文字位置
System.out.println(str.indexOf('d')); //3:どの位置に存在するか
System.out.println(str.indexOf("abcd")); //0:文字列が始まる最初の文字位置
System.out.println(str.indexOf("abcdef")); //-1:存在しない場合は-1
Stringクラスのsubstringメソッドに関する問題
String str = "abcde";
System.out.println(str.substring(2, 4)); //cd:
System.out.println(str.substring(2)); //cde:開始位置以降の全てを取得
System.out.println(str.substring(2, 6)); //例外処理
String str2 = "abc def";
System.out.println(str2.substring(2, 5)); //c d:半角もカウント
Stringクラスのreplaceメソッドに関する問題
String str = "aaaa";
System.out.println(str.replace("aa", "b")); //bb:置換
System.out.println(str.replace("aa", 'b')); //コンパイルエラー:混合した型は不可
StringクラスのatartsWithメソッドに関する問題
String str = "abcde";
System.out.println(str.substring(1, 3).startsWith("b")); //true:bから開始の為
System.out.println(str.substring(1, 3).startsWith("a")); //false:aから開始ではない為
System.out.println(str.substring(1, 3).endsWith("c")); //true:cで終了の為
Stringオブジェクトの結合に関する問題
concatの使用方法
String str = "Hello, ".concat("Java!");
System.out.println(str); //Hello, Java!
appendの使用方法
StringBuilder str = new StringBuilder("Java!");
System.out.println("Hello, " + str); //Hello, Java!
StringBuilderクラスに関する問題
StringBuilder sb = new StringBuilder();
sb.append("abcde"); //abcde:追加
sb.reverse(); //edcba:反転
sb.replace(1, 3, "a"); //eaba:開始位置から終了位置までの範囲を置換
System.out.println(sb);
第3章 演算子と判定構造
マイナス演算子に関する問題
int num = -10;
System.out.println(10 * -num); //10 * (-1 * -10) → 100
System.out.println(10 * - num); //スペースがあっても反転する
型変換に関する問題
データ型 | 値 |
---|---|
boolean | true or false |
byte | 8ビット整数 -128~127 |
short | 16ビット整数 -32,768~32,767 |
2進数から10進数への計算方法
例:10000000→128
値 | 値 | 値 | 値 | 値 | 値 | 値 | 値 |
---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
ビットが1の箇所を合計すると計算ができる。
インクリメントとデクリメントに関する問題
前置と後置の違いで演算の動作順序が異なるのが重要。
int a = 10;
int b = a++ + a + a-- - a-- + ++a;
System.out.println(b); //32
型 | 説明 |
---|---|
前置インクリメント(++a) | まずaの値を1増やし、それから新しいaの値を評価 |
後置インクリメント(a++) | まず現在のaの値を評価し、それからaの値を1増加 |
前置デクリメント(--a) | まずaの値を1減らし、それから新しいaの値を評価 |
後置デクリメント(a--) | まず現在のaの値を評価し、それからaの値を1減少 |
数値演算に関する問題
「<」「<=」「>」「>=」の4つは数値の大小を比較するのみ(数値以外は比較不可)
同一性と同値性に関する問題
型 | 説明 | 判定方法 |
---|---|---|
同一性 | 複数の変数が同じインスタンスを参照している性質のこと | ==演算子 |
同値性 | インスタンスは異なるけど、同じ値を持っていること | equalsメソッド |
Sample s1 = new Sample(10);
Sample s2 = s1; //変数s1とs2は同じ参照(同一)
s1 = new Sample(10); //別のインスタンスを生成して、s1に代入(no 同一)
System.out.println(s1 == s2);
同値性の確認方法は各クラスによって異なる為、
equalsメソッドは「オーバーライド」して使うことが前提になる。
覚えておくべき条件:null以外の参照値xについてx.equals(null)はfalseを返す
文字列リテラルの同一性を確認する問題
String a = "sample";
String b = "sample";
System.out.println(a == b); //true
System.out.println(a.equals(b)); //true
■コンスタントプール
Stringクラスのみの仕組みで、同じ文字列ならインスタンスを使いまわす。
String a = "sample";
String b = new String ("sample"); //別インスタンスになる
System.out.println(a == b); //同一インスタンスではないため、false
System.out.println(a.equals(b)); //同値のため、true
Stringクラスのinternメソッドに関する問題
コンスタントプールの文字列を探し、同じ文字列が存在すればその文字列を返す。
同じ文字列が存在しない場合は新たに文字列を生成する。
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1 == str2); //false
System.out.println(str1.intern() == str2.intern()); //true
IF文の構文に関する問題
javaにおいては3種類ある。
- if
- if-else
- if-else if-else
中括弧は省略可能
if(false)
System.out.println("A");
System.out.println("B");
↓
if(false) {
System.out.println("A");
}
System.out.println("B");
switch文に関する問題
switch(条件式) {
case 値 : 処理
break;
case 値 : 処理
break;
default : 処理
break;
}
条件式には値の型に宣言がある
型 | 説明 |
---|---|
int型以下の整数型とラッパークラス | int、byte、short、Integer、Byte、Short |
文字と文字列 | char、String |
列挙型 | Enum |
case値にも条件がある。
- 条件式が戻す値と同じ型か互換性がある型であること
- 定数であるか、コンパイル時に値を決めることが出来ること
- nullではないこと(変数も不可)
breakを記述しない場合は、以降に現れる全てのcase式がbreak出るまで処理される。
※default式も対象になる※
do-whileに関する問題
do {
//繰り返し処理
} while (条件式)
- doの後ろにカッコ「()」が付かない
- whileの後ろに条件式を記述する
- セミコロン「;」で終了する
中カッコを省略した場合
- 次の1文だけ繰り返し処理として扱う。
- doとwhileの間には1文のみを記述でき、2文以上はコンパイルエラー。
int cnt = 0;
while(cnt++ < 5)
System.out.println("A"); //繰り返し AAAAA
System.out.println("B"); //繰り返さない B
↓
↓中カッコ有り
↓
int cnt = 0;
while(cnt++ < 5) {
System.out.println("A");
}
System.out.println("B");
for文の構文に関する問題
for ( 初期化文; 条件文; 更新文 ) {
// 繰り返し処理
}
■条件文
初期化文や更新文のようにカンマ「,」で区切って複数記述は不可。
複数の条件を記述したい場合、論理演算子を使用。
for(int i = 0. j = 0; i < 3, j < 5; i++) //コンパイルエラー
for(int i = 0. j = 0; i < 3 && j < 5; i++) //正しい書き方
変数のスコープに関する問題
javaの変数は宣言したブロック内(中カッコの範囲)でのみ有効
int a = 1;
for(int b = 2, total = 0; b <= 5; b++) {
total = a * b;
}
System.out.println(total); //コンパイルエラー
二重ループを使った問題
外側のループが回る間に、内側のループが回る。
例:外側3回×内側3回=9回
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; i++) {
System.out.println("hello"); //helloが9回処理される
}
}
二次元配列の理解チェック
int array[][] = new int[][] {{1, 2}, {2, 3, 4}};
System.out.println(array[0][0]); //1
System.out.println(array[0][1]); //2
System.out.println(array[1][0]); //2
System.out.println(array[1][1]); //3
System.out.println(array[1][2]); //4
array.length; //2
/*
配列の「行」の数を返す。
Javaにおける二次元配列は、本質的に「配列の配列」
したがって、一次元目(つまり、「行」の配列)の長さを得る
*/
array[0].length; //2
array[1].length; //3
//配列の「行の列」の数を返す。
[0] | [1] | [2] | |
---|---|---|---|
[0] | 1 | 2 | |
[1] | 2 | 3 | 4 |
無限ループを使った問題
//無限ループ(While文)
while (true) {
// do something
}
//無限ループ(for文の条件にリテラル「true」を記述)
for (int i = 0; true ; i++) {
// do something
}
//無限ループ(for文の条件式を省略)
for (int i = 0; ; i++) {
// do something
}
//無限ループ(for文の更新文を省略)
for (int i = 0; i < 5;) { //変数iの値が0のまま
// do something
}
拡張for文を使った問題
for (型 変数名 : 集合) {
//繰り返し処理
}
配列とStringに互換性はない
(そういうことでは無さそう・・)
for (String str : array) // ✕
第4章 制御構造
ラベルの使用に関する問題
ループに使われることが多いけど、以下もOKです。
- コードブロック
- すべてのループ文と分岐(if、swith)
- 式
- 代入
- return文
- tryブロック
- throw文