Open4

Oracle Certified Java Programmer, Silver SE 11 認定資格の学習ログ

wateruwateru

第1章 簡単なJavaプログラムの作成

パッケージに関する問題

パッケージの目的は3つ

  1. 名前空間を提供し、名前の衝突を避ける
  • 名前空間:
    • あるものの「名前」を付ける際に、その名前が別のものの「名前」と同じ場合、名前だけでは「どちらなのか」が分からないため、このような場合には名前を付けることができない。
    • 慣習でドメイン名を逆にした文字列をパッケージ名に利用
  • 完全修飾クラス名:
    • パッケージ名.クラス名
      (例:java.util.ArrayList)※util:ユーティリティのことで、「役に立つもの」
  1. アクセス修飾子と組み合わせてアクセス制御機能を提供する
  • パッケージ単位でアクセス制御が可能
// 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 × × ×
※すべて=他のパッケージを含む
  1. クラスの分類を可能にする
  • パッケージはディレクトリ構造とマッピングされます。
  • 例:jp.co.xxx.Sampleという完全修飾クラス名を持つクラス
jp/
 ├ co/
   ├ xxx/
    ├ Sample.class

パッケージ宣言に関するルールを覚える。

  1. 必ずソースコードの先頭行に記述
  2. 宣言より前に記述できるのはコメントのみ
// 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を起動するためのコマンド(以下、構文)

java 完全修飾クラス名 [引数1 引数2 ・・・]

引数=「起動パラメーター」や「コマンドライン引数」と呼ぶ
配列型変数argsで参照できる(args[0] = 引数1)

■実行の動作

  1. javaコマンドを実行
  2. JVMを起動する
  3. 指定されたクラスをクラスパスから探し出してロード
  4. String配列型オブジェクトを作成し、起動パラメーターを格納
  5. 起動パラメーターを保持した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となります。

wateruwateru

第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);
wateruwateru

第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) // ✕
wateruwateru

第4章 制御構造

ラベルの使用に関する問題

ループに使われることが多いけど、以下もOKです。

  • コードブロック
  • すべてのループ文と分岐(if、swith)
  • 代入
  • return文
  • tryブロック
  • throw文