【Java Silver黒本】6章のつまづいたところまとめ。

可変長引数

  • メソッド内では配列として扱われる
  • 可変長引数は引数リストの最後に記述する
  • 可変長引数は各メソッドに最大ひとつまで
public class Main {
  // メソッド内では配列として扱われる
  public static void sampleMethod1(String text, int... numbers) {
    System.out.println(numbers instanceof int[]); // => true
  }

  // 可変長引数は引数リストの最後に記述する
  // 次のメソッドはコンパイルエラーになる
  public static void sampleMethod2(int... numbers, String text) {

  }

  // 可変長引数は各メソッドに最大ひとつまで
  // 次のメソッドはコンパイルエラーになる
  public static void sampleMethod3(int... numbers, String... texts) {

  }
}

return文

  • return文の使用で明らかに到達不可能なコードがある場合、コンパイルエラーになる
public class Main {
  public static void main(String[] args) {
    return;

    // コンパイルエラー
    System.out.println("Hello");
  }
}

オーバーロード

public class Main {
  public static void main(String[] args) {

  }

  // 元のメソッド
  public static void sampleMethod(int number) {

  }

  // 引数だけ変える
  // 次のメソッドは元のメソッドのオーバーロードとして動作する
  public static void sampleMethod() {

  }

  // 戻り値だけ変える
  // 次のメソッドはコンパイルエラーになる
  public static String sampleMethod(int number) {
    return "hello";
  }

  // アクセス修飾子だけ変える
  // 次のメソッドはコンパイルエラーになる
  private static void sampleMethod(int number) {

  }
}

あいまいなメソッド呼び出し

  • オーバーロードした複数のメソッドがあり、呼び出し時の実引数指定でどちらのメソッドを使用するか特定できない場合、コンパイルエラーとなる
public class Main {
  public static void main(String[] args) {
    // コンパイルエラー
    sampleMethod(1, 2);
  }

  public static void sampleMethod(int a, double b) {

  }

  public static void sampleMethod(double a, int b) {

  }
}

コンストラクタ定義ルール

  • メソッド名をクラス名と同じにする
  • 戻り値型は記述しない
  • newと一緒にしか使えない

※戻り値型を記述すると、メソッドとして扱われる。

public class Main {
  public static void main(String[] args) {
    Item item = new Item();

    item.Item(); //=> hello
  }
}

class Item {
  // コンストラクタを明示的に記述しない場合、
  // コンパイル時に引数なしのコンストラクタが自動で追加される

  // 次のItem()は戻り値型の記述があるため
  // コンストラクタではなくメソッドとして解釈される
  void Item() {
    System.out.println("hello");
  }
}

privateにすることも出来る。

public class Main {
  public static void main(String[] args) {
    Item item1 = Item.createInstance();
    Item item2 = Item.createInstance();

    System.out.println(item1 == item2); // => true
  }
}

class Item {
  public static Item instance;

  private Item() {

  }

  public static Item createInstance() {
    if(Item.instance == null) {
      Item.instance = new Item();
    }

    return Item.instance;
  }
}

初期化ブロック

  • クラス宣言の中にブロックだけを記述すると、初期化ブロックとなる
  • 初期化ブロックは全てのコンストラクタの実行前に実行される
public class Main {
  public static void main(String[] args) {
    Item item = new Item();
    // => hello
    // => world
  }
}

class Item {
  public Item() {
    System.out.println("world");
  }

  // 初期化ブロック
  {
    System.out.println("hello");
  }
}

コンストラクタのオーバーロード

  • コンストラクタのオーバーロードの際、別のコンストラクタ呼び出しは処理の最初でなければならない
public class Main {
  public static void main(String[] args) {
    Item item = new Item();
  }
}

class Item {
  public Item(String text) {

  }

  public Item() {
    // 別のコンストラクタ呼び出しthis("fuga")より前に処理があるので
    // コンパイルエラーとなる
    System.out.println("hoge");

    this("fuga");
  }
}

アクセス修飾子によるアクセス制御

アクセス修飾子 アクセス可能範囲
public 全てのクラスからアクセス可
protected 同パッケージ、
もしくは継承クラスからのみアクセス可
記述なし 同パッケージからのみアクセス可
private クラス内からのみアクセス可
  • クラス宣言にはpublicと記述なしのみ使用可
  • インナークラスにはprivateも使用可
  • 記述なしはpackage privateとも表現される

実引数と仮引数

  • 実引数はコピーされて仮引数へ渡されるため、仮引数が変更されても実引数に影響はない
public class Main {
  public static void main(String[] args) {
    int number = 1;

    sampleMethod(number);

    System.out.println(number); // => 1
  }

  public static void sampleMethod(int number) {
    number = 10;
  }
}