新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。もう新人じゃないかも…

OCJP SIlver SE7資格の学習

[Java] OCJP Silver SE7資格の学習

概要

  • Java SE7 認定資格:日本オラクルが実施するJavaプログラマ向けの資格
    • Bronze:基礎知識が問われる入門資格
    • Silver:Javaの仕様を細部まで理解していることが問われる中級資格
    • Gold:受験にSilver資格が必要。設計に関する知識も問われる高度試験(スレッド、JDBCデザパタ含む)
  • 試験概要
    • 問題数:90問
    • 時間:150分
    • 合格ライン:75%

参考文献

オラクル認定資格教科書 Javaプログラマ Silver SE 7

オラクル認定資格教科書 Javaプログラマ Silver SE 7

内容

識別子の制限
  • 使えるのは英数字・_・$
  • 数字は先頭には使用不可
  • キーワード(public, caseなど)・リテラル(true, nullなど)そのままは使用不可
mainメソッド
  • プログラムの実行時に呼ばれるのは、以下の特徴を持ったmainメソッド
    • public かつ static(順不同)
    • 返却値の型がvoid
    • 引数の型がString[](String...でも可)
  • 呼ばれないmainメソッドを定義してもよく、書式が正しければコンパイルエラーにはならない
// 基本の形
public static void main(String[] args) { ... }

// staticとpublicは入れ替わっても良い
static public void main(String[] args) { ... }

// 引数の名前は何でも良い
public static void main(String[] hogehoge) { ... }

// 可変長引数はコンパイル時に配列に変換される
public static void main(String... args) { ... }

/* 以下は実行時には呼ばれないが、コンパイルエラーにはならない */
public void main(String[] args) { ... }
public static void main(int args) { ... }
public static int main(String[] args) { ... }
パッケージ化されたクラスを使用するには
  1. 使用するクラスのインポート宣言を行う
  2. 使用するクラスと同じパッケージに属するパッケージ宣言を行う
java.langパッケージ
  • インポート宣言せずに使用可能
==演算子とequals()メソッド
  • ==演算子:オブジェクト情報の参照情報が一致するかどうか
  • Objectクラスのequals():同上
  • StringBuilderのequals():同上(Objectクラスのまま)
  • Stringクラスのequals():変数の指す中身が同一文字列かどうか
String str1 = "hoge";
String str2 = "hoge";
String str3 = new String("hoge");

if (str1 == str2) ; // -> true! Stringの場合は参照も同じになる
if (str1.equals(str2)) ; // -> true!

if (str1 == str3) ; // -> false! コンストラクタで文字列を指定すると別のインスタンスが生成される
if (str1.euqlas(str3)) ; // -> true!

StringBuilder sb1 = new StringBuilder("hoge");
StringBuilder sb2 = new StringBuilder("hoge");

if (sb1 == sb2) ; // -> false! 異なる参照
if (sb1.equals(sb2)) ; // -> false! StringBuilderクラスではObjectクラスのequals()メソッドをオーバーライドしていないため
インクリメント・デクリメント演算子の優先順位と評価順序
  • 前置:評価後(すぐ)にインクリメント
  • 後置:インクリメント後に評価
int i = 0, j = 0;
i = (j++);
// 1) jが0と評価され、jがインクリメント
// 2) iには0が入る
// 注:()を付けても変わらない

int i = 0, j = 0;
i = (j++) + (j++);
// 1) 左のjが0と評価され、jがインクリメント
// 2) 右のjが1と評価され、jがインクリメント
// 3) i = 0 + 1の結果、iには1が入る
文字列の結合順序
String name;

name = "hoge" + 1 + 2;
// 1) "hoge" + 1が評価され、"hoge1"に
// 2) "hoge1" + 2が評価され、"hoge12"に

name = "hoge" + 1 * 2;
// 1) 1 * 2が評価され、2に
// 2) "hoge" + 2が評価され、"hoge2"に
条件式内の処理
  • (hoge && huga) -> hogeがfalseなら、hugaの判定はしない
  • (hoge || huga) -> hogeがtrueなら、hugaの判定はしない
  • hugaが例外を発生させるような場合も、hugaの判定が行なわれないような場合には例外が発生しない
break文
  • ループ文かswitch文でしか使用できない
  • それ以外ではコンパイルエラー
switch文で使用できるデータ型
  • 使用できる
    • byte, short, int, charとそのラッパークラス
    • 列挙型
    • String(Java SE 7から)
  • 使用できない
    • double, float, longはダメ
同一のcase文
  • switch文では同一のcase文は宣言不可(コンパイルエラー)
switch(num) {
    case 1:
    ...
    break;
    case 1:  // <- コンパイルエラー!
    ...
    break;
    default:
    break;
初期値
  • 基本数値型:0(floatは0.0f, doubleは0.0d)
  • char:'¥u0000'、つまり空白
  • boolean:false
  • 参照型:null
長さの異なる多次元配列
int[][] hoge = { {0}, {1, 2} };
// hoge[0][0] = 0;
// hoge[1][0] = 1;
// hoge[1][1] = 2;
// hoge[0][1] <- IndexOutOfBoundsException!
多次元配列の長さ
int[][] i = ...;
// i.length <- 1次元の要素数
// i[0].length <- 2次元の[0]配列の要素数
ジェネリックスの記述
ArrayList<String> list = new ArrayList<String>();
// Java SE7から以下でもOK
ArrayList<String> list = new ArrayList<>();
ArrayListのadd()メソッド
  • add(index, element)のindexの範囲は、index >= && index <= size() でなければいけない
    • それ以外だと実行時にArrayIndexOutOfBoundsExceptionが発生
ブロック内で宣言した変数はブロック外では使用不可
// Error!
for (;; ++i) {
    int i = 0;
}

// Error!
do {
   int i = 0;
   i++;
} while (i < 10);
staticメソッドインスタンスメソッドの制約
オーバーロード
  • 引数の型・数が異なれば、戻り値の型も異なっていても良い
    • 逆に言えば、引数の型・数が同じならば、戻り値の型は同じである必要がある
    • オーバーライド時も同じ
void foo() { ... }
void foo(int i) { ... }
String foo (String str) { ... }
  • 暗黙の型変換
    • shortを引数にメソッドを呼んだとき、以下の順で呼ばれる
    • int, long, float, double
// 引数intのfooが呼ばれる
void foo(int i) { ... }
void foo(long i) { ... }
void foo(float i) { ... }
void foo(double i) { ... }

public static void main(String[] args) {
    short s = 5;
    // 大きさと性質で一番近い型が呼ばれる
    foo(5);
}
型の暗黙キャスト
  • char型
    • char -> Stringへの暗黙キャストはない
    • char -> int, long, float, doubleへは暗黙キャストされる
  • 基本型
    • 基本型 -> 基本型へは、より大きい型へは暗黙キャストされる
    • 基本型 -> ラッパークラスへは、対応する型なら暗黙キャストされる
      • ○int -> Integer, short -> Short
      • ×int -> Long, float -> Float
  • ラッパークラス
    • ラッパークラス -> 基本型時は、一旦対応する基本型にアンボクシングされ、その後は基本型に準じる
      • ○Integer -> int, Short -> (short) -> long
      • この際、オブジェクトがnullだとNullPointerExceptionが発生する
    • ラッパークラス -> ラッパークラスは暗黙キャストされない
      • ×Integer -> Long, Float -> Double
  • まとめ
    • 基本型同士は、より大きい型へは暗黙キャストされる
    • オートボクシング(基本->ラッパー)されるのは、対応する型のみ
    • アンボクシング(ラッパー->基本)は自動で対応する型にされるが、その後は基本型同士のルールに準じる
コンストラクタの明示的呼び出し
  • コンストラクタを明示的に呼び出している際には、
    • thisまたはsuperは使えない(オブジェクト生成前だから?)
    • インスタンス変数は使えない
    • static変数なら使用可能(ロード時に生成されるため?)
int num;
int x;
static int y;

public Hoge(int num) {
    this.num = num;
}

public Hoge() {
    this(10);    // <- OK!
    // this(this.x);  <- thisは使えない!
    // this(x);         <- インスタンス変数は使えない!
    // this(y);  <- static変数なのでOK!
}
クラスのフィールドのアクセス権限について
  • フィールドのアクセス権限の前に、まずクラスの修飾子で制限される
// 修飾子なしなのでパッケージプライベート
class Hoge {
    // hugaはpublicではあるが、クラスの制限により同一パッケージからしかアクセス不可
    public String huga = "hello";
}
スーパークラス・サブクラス間の代入
// スーパークラスの変数へはキャストなし(暗黙)で代入可能
Super s = new Sub();
// サブクラスの変数へはキャストが必要
Sub sub = (Sub) s;

// サブクラスの変数へは代入不可
Sub sub = new Super();  // <- エラー!
// サブクラスのオブジェクトの情報がないとそもそもダメ
Sub sub = (Sub) new Super(); // <- Superオブジェクトしか生成されておらず、Subに必要なデータがない
catch文を連ねる場合
try {
    ...
} catch (Exception e) {
    ...
} catch (RuntimeException e) { // -> error!
    ...
}
オーバーライドしたメソッドでのthrows宣言
class Super {
    void hoge() throws Exception { ... }
}
class Sub extends Super {
    void hoge() throws RuntimeException { ... } // OK!
}
class Super {
    void hoge() throws Exception { ... }
}
class Sub extends Super {
    void hoge() throws { ... } // OK!
}
...

public static void main(String[] args) {
    Super super = new Super();
    try {
        // スーパークラスのhogeが呼ばれるのでcatch必須!
        super.hoge();
    } catch(Exception e) { ... } 

    Sub sub = new Sub();
    // サブクラスのhogeが呼ばれるのでcatch不要!
    sub.hoge();

    super = sub;
    try {
        // サブクラスのhogeが呼ばれるが、
        // 変数がsuper型なので(コンパイラ的に?)catchが必要!
        super.hoge();
    } catch(Exception e) { ... }
}
スーパークラス型の変数にサブクラス型のインスタンスの参照を入れた場合のあれこれ
class Super {
    int num;
    static String str;

    void hoge() { ... }
    static void nyoro() { ... }
}

class Sub extends Super {
    int num;
    static String str;

    void hoge() { ... }
    static void nyoro() { ... }

    static public void main(String[] args) {
        Super s = new Sub();
        s.num = 10; // -> Superクラスのnumが呼ばれる
        s.str = "hoge"; // -> Superクラスのstrが呼ばれる
        s.hoge();  // -> Subクラスのhoge()が呼ばれる
        s.nyoro();  // -> Superクラスのnyoro()が呼ばれる
}

コンストラクタの暗黙的呼び出し
class Super {
    String name;
    public Super(String name) {
        this.name = name;
    }
}

class Sub extends Super {
    public Sub() {
        // ここに自動でsuper()が追加され、コンパイルエラーになる
        this.name = "Sub";
    }
}

所感

  • やたら細かいところを聞かれる。知識を含めたコードの解読がメイン。
    • プログラム的には良くないコードを解読するものが多い(mainメソッドがいっぱいあったり)
    • スーパークラスの変数にサブクラスの参照を入れたり戻したりまた入れたり…
    • 150分で90問解くので、ある程度複雑な問題は後回しにした方がいいかも
  • 選択式だが、そこまで楽ではない
    • コンパイルエラーになる」の選択肢があると厄介、詳しくコードを読む必要があるので
    • 「3つ正しいものを選べ」などもちゃんと理解していないと正解は難しい
  • 全体の7割程度は(わかっていれば)単純な問題なので、そこを落とさないようにしつつひっかけ問題も解けるようにする