0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Java11 Gold 資格 学習

Last updated at Posted at 2024-06-01

Java 11 Silver & Gold 受験対策 & 今後の備忘録

Javaのデータ型にはプリミティブ型参照型がある。

参照型には更にクラス型、配列型、列挙型などの分類がある。

  • プリミティブ型
    • boolean
    • char
    • byte
    • short
    • int
    • long
    • float
    • double
  • 参照型
    • クラス型
    • インターフェース型
    • 配列型
    • 列挙型

プリミティブ型

サイズ 説明 ラッパー
boolean 仕様無 真偽値 true, false Byte
char 16bit Unicode文字 ¥u0000 ~ ¥uFFFF Character
byte 8bit 整数 -128 ~ 127 Byte
short 16bit 整数 -32768 ~ 32767 Short
int 32bit 整数 -2137383648 ~ 2147483647 Integer
long 64bit 整数 -9223372036854775808 ~ 9223372036854775807 Long
float 32bit 単精度浮動小数点数 ±3.40282347E+38 ~ 1.40239846E-45 Float
double 64bit 倍精度浮動小数点数 ±1.79769313486231570E+308±4.94065645841246544E-324 Double

String型はプリミティブ型ではなく参照型

参照型

クラス型、配列型、列挙型がある。

リテラル

整数リテラル

デフォルトではint型として扱われる。

整数リテラルをlong型として扱いたい場合、末尾にlもしくはLの接尾辞をつける。

long a = 100L;

また整数リテラルをshort型やbyte型として扱うための接尾辞は存在しない。その代わりにint型とshort型などは自動変換される。

// 10はint型として扱われる整数リテラルだが、short型に代入できる(short型に自動変換される)
short i = 10;

10進数、2進数、8進数、16進数

デフォルトでは10進数として扱われる。

2進数で表したい場合、0bを接尾辞としてつける。

byte ichi = 0b0001;  // 1
short ni = 0b0010;   // 2
int san = 0b00011;   // 3

System.out.println(ichi);
System.out.println(ni);
System.out.println(san);
// >> 1
// >> 2
// >> 3

8進数で表したい場合、0を接尾辞としてつける。

byte nana = 07;     // 7
short hachi = 010;  // 8
int kyu = 011;      // 9

System.out.println(nana);
System.out.println(hachi);
System.out.println(kyu);
// >> 7
// >> 8
// >> 9

16進数で表したい場合、0xを接尾辞としてつける。

byte jugo = 0xF;     // 15
short juroku = 0x10; // 16
int junana = 0x11;   // 17

System.out.println(jugo);
System.out.println(juroku);
System.out.println(junana);
// >> 15
// >> 16
// >> 17

浮動小数点数リテラル

デフォルトではdouble型として扱われる。

float型として扱いたい場合、末尾にfもしくはFの接尾辞をつける。

float a = 100.0F;

真偽リテラル

boolean型として扱われる。

文字リテラル

char型として扱われる。

文字リテラルはシングルコーテーション')で囲う必要がある。

またJavaは Unicode を文字コードとして採用していて、Unicodeエスケープシーケンスを使って文字を表現する際にはバックスラッシュ\)を使用する。(Windows環境では¥

Unicode の文字は U+0000 ~ U+FFFFまでの文字コードが存在するが、Javaでは\u0000 ~ \uFFFFで表現する。

char komoji = '\u0061';
char omoji = '\u0041';

System.out.println(komoji);
System.out.println(omoji);
// >> a
// >> A

文字リテラルは直接16進数や10進数でも表現できる。(0x0000 ~ 0xFFFF は10進数では 0 ~ 65535であるため、次のような表現も可能。

char komoji = 0x0061;
char komoji2 = 97; // 0x0061 = 97

char omoji = 0x0041;
char omoji2 = 65; // 0x0041 = 65

System.out.println(komoji);
System.out.println(komoji2);
// >> a
// >> a

System.out.println(omoji);
System.out.println(omoji2);
// >> A
// >> A

char型の変数に文字列リテラルは代入できない。

char ok = 'a'; // 有効
char error = "a"; // コンパイルエラー

Javaはシングルコーテーションとダブルコーテーションに明確な違いがあるため注意。

文字列リテラル

String型として扱われる。

文字列リテラルはダブルコーテーション")で囲う必要がある。

String

String型はプリミティブ型ではなく参照型(java.lang.String)に分類される。

Stringクラスは内部で文字列をchar型の配列として扱っている。

String型はインターフェースCharSequenceの実装クラスでもある。

String型のインスタンス化

参照型のデータ型はnew演算子によってインスタンス化を行う。

MyClass a = new MyClass();

ただし、String型だけは特別扱いで、文字列リテラルによってString型のインスタンスが生成できるようになっている。

String a = "hello world"; // String型はプリミティブ型ではなく参照型

immutable

Stringクラスは immutable なクラスであるため、一度生成したインスタンスは中身を変更することができない。

String型変数への再代入は、インスタンスの中身変更ではなく実際にはインスタンス新規生成を意味する。

// インスタンスに変更を加えているように見えるが、実際にはインスタンスを変更している訳ではない
String a;
a = "hello world";
a = "ABCD";
// 実際は immutable なインスタンスを新規生成している
String a;
a = new String("hello world");
a = new String("ABCD");

このため、subString()concat()toUpperCase()などのメソッドが返すインスタンスは、実行されたメソッドのインスタンスではなく、新しいインスタンスということになる。

コンスタントプール

前述の通り、「文字列リテラルの使用」は「java.lang.Stringクラスのインスタンス生成」を意味する。

しかし実際の文字列リテラルは、同じものが頻繁に使用されることが多い。同じ文字列であるのにわざわざ別のインスタンスとして扱うメリットはなく、逆に新たなインスタンス生成の度にメモリ領域が必要になってしまい非常に非効率になる。

String a = "hello world";
String b = "hello world";
String c = "hello world";
String d = "hello world";

そのため文字列リテラルにはコンスタントプールという仕組みがある。

コンスタントプールは文字列リテラルから生成されたStringインスタンスを管理するためのメモリ領域のことを指す。

通常、文字列リテラルが使用されるとまず最初に定数用のメモリ空間(コンスタントプール)にその文字列リテラルから生成されたインスタンスが既に存在しないかがチェックされる。存在しない場合に限り、String型インスタンスが生成され、生成されたインスタンスがコンスタントプールに配置される。

この仕組みにより、同じ文字列リテラルからString型インスタンスを生成する際は、過去に生成されたStringインスタンスへの参照が再利用される。

// 同じインスタンスへの参照が再利用されていることがわかる
String a = "hello world"; // コンスタントプール生成
String b = "hello world"; // コンスタントプールに存在するインスタンスへの参照を再利用
String c = "hello world"; // コンスタントプールに存在するインスタンスへの参照を再利用
String d = "hello world"; // コンスタントプールに存在するインスタンスへの参照を再利用

if (a == b && b == c && c == d) {
    System.out.println("各変数は同じインスタンスを参照している");
}
// >> 各変数は同じインスタンスを参照している

ただし、プログラムの中で動的に生成された文字列はコンスタントプールに配置されない。また明示的にnew演算子によって生成されたインスタンスが生成された場合、Stringインスタンスはコンスタントプールからの再利用は行われない。

Stringクラスのintern()メソッドは、コンスタントプール(を含むメモリ領域)内からStringインスタンスを検索してその参照を返すことができる。

String a = "hello world";
// 明示的にnewしているので、コンスタントプールからのインスタンスの再利用、またはコンスタントプールへの保存がされない
String b =  new String("hello world");

if (a == b) {
    System.out.println("同じインスタンスを参照している");
}else{
    System.out.println("別のインスタンスを参照している");
}
// >> 別のインスタンスを参照している

if (a == b.intern()) {
    System.out.println("同じインスタンスを参照している");
}else{
    System.out.println("別のインスタンスを参照している");
}
// >> 同じインスタンスを参照している

初期値

クラスのフィールドは、デフォルトで初期化されるため、int型のメンバ変数は0boolean型はfalse、参照型のメンバ変数はnullに初期化される。

一方メソッド内のローカル変数は、明示的に初期化されない限り初期値が設定されない。

class MyClass {
    int a; // 0に初期化される
    boolean b; // falseに初期化される
    String c; // nullに初期化される

    void myMethod() {
        int x; // 初期化されない
        System.out.println(x); // コンパイルエラー
    }
}

型推論・ジェネリクス・共変性・反変性

初期化子(Initializer)

クラスの初期化時に特定のコードを実行するための特殊なブロックのこと。

static初期化子(static initializer)とインスタンス初期化子(instance initializer)がある。

static初期化子

クラスがロードされるときに一度だけ実行されるコードブロック。

class MyClass {
    static {
        System.out.println("hello world");
    }
}

静的なフィールドを初期化する際に有効。

class MyClass {
    static int a;
    
    static {
        a = 10;
    }
}

インスタンス初期化子

インスタンス生成の度に実行されるコードブロック。

コンストラクタの前に実行される。

class MyClass {
    {
        System.out.println("hello world");
    }
}

オーバーロードによるコンストラクタが複数あるような場合に、全てのコンストラクタに共通の処理をまとめたい時などに有効。

class MyClass {
    {
        // コンストラクタの前に実行される
        System.out.println("共通処理");
    }

    MyClass(int a) {
        System.out.println("コンストラクタ1");
    }

    MyClass(int a, int b) {
        System.out.println("コンストラクタ2");
    }
}

実行順

  1. スーパークラスのstatic初期化子
  2. サブクラスのstatic初期化子
  3. スーパークラスのインスタンス初期化子
  4. スーパークラスのコンストラクタ
  5. サブクラスのインスタンス初期化子
  6. サブクラスのコンストラクタ
SuperClass
class SuperClass {
    static {
       System.out.println("①static initializer of super class");
    }

    {
        System.out.println("③instance initializer of super class");
    }

    SuperClass(){
        System.out.println("④constructor of super class");
    }
}
SubClass
class SubClass extends SuperClass{
    static {
        System.out.println("②static initializer of sub class");
    }

    {
        System.out.println("⑤instance initializer of sub class");
    }

    SubClass(){
        System.out.println("⑥constructor of sub class");
    }
}
実行順
SuperClass a = new SubClass();
// >> ①static initializer of super class
// >> ②static initializer of sub class
// >> ③instance initializer of super class
// >> ④constructor of super class
// >> ⑤instance initializer of sub class
// >> ⑥constructor of sub class

ネストしたクラス

ストリーム

入出力

JBDC

アノテーション

Enum

JavaのEnumはクラス。

定義したEnumはjava.lang.Enumクラスのサブクラスとして扱われる。

定義した列挙子は、それぞれが列挙型から生成されたインスタンスとして扱われる。

public enum Fruits {
    Apple, // Fruits型インスタンス
    Banana, // Fruits型インスタンス
    Orange, // Fruits型インスタンス
}

コンストラクタやフィールドを定義する事ができる。ただし、コンストラクタはprivateでなけらばならず、省略した場合には暗黙的にprivateと解釈される。明示的にpublicとした場合、コンパイルエラーが発生する。

public enum Fruits {
    Apple(1), // Fruits型インスタンス
    Banana(2), // Fruits型インスタンス
    Orange(3); // Fruits型インスタンス
    
    private int id;

    // privateと解釈される
    Fruits(int id){
        this.id = id;
    } 
}

ローカライズ

プロパティファイル

例外

Error.png

アサーション

アサーションの構文は以下の通り。

アサーション
assert 条件式 : "メッセージ";

アサーションはでフォルドでは無効になっているため、実行時に-eaオプションをつける必要がある。

$ java -ea com.sample.app.Main

モジュールシステム

試験対策としての早見表

文法的な暗記系知識。

実行

起動パラメータにスペースを含めたい場合、ダブルコーテーション「"」で囲う

起動パラメータにスペースを含めたい場合、ダブルコーテーション「"」で囲う
java Main.java "hello world"

起動パラメータにダブルコーテーション「"」を使いたい場合、エスケープする

LinuxOSの場合はバックスラッシュ「\」、Windowsの場合は「¥」を使用する

起動パラメータにダブルコーテーション「"」を使いたい場合、エスケープする
java Main.java \"

上の例では「"」がパラメータとして渡される。

エスケープされないダブルコーテーション「"」は無視される

エスケープされないダブルコーテーション「"」は無視される
java Main.java a"bc"

上の例では「abc」がパラメータとして渡される。

アクセス修飾子

protectedとデフォルトの違いに注意して覚える

修飾子 可視性
private - 同じクラス内からのみ
なし(デフォルト) ~ 同じパッケージ内からのみ
protected # 同じパッケージ内 + 継承関係にあるサブクラス からのみ
public + 全て

for文

初期化文と更新文はコンマ(,)で区切って複数記述することができる

初期化文と更新文はコンマ(,)で区切って複数記述することができる
for (int i = 0, j = 0; i < 10; i++, j--) {
    // 処理 
}

ただし初期化では同じ型しか記述できない

コンパイルエラー
// コンパイルエラー
for (int i = 0, long j = 0; i < 10; i++, j--) {
    // 処理 
}

条件式と更新式は省略できる

条件式を省略した場合
for (int i = 0; ; i++) {
    // 処理
}
更新式を省略した場合
for (int i = 0; i < 10; ) {
    // 処理
}

breakで抜けるのは直近のループだけ

breakで抜けるのは直近のループだけ
 for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
        if(条件){
           braek; 
        }
    }
    // ここに抜ける
}
// ここには抜けない

switch文

switch文の条件式にはboolean型やlong型、float型、double型を使用することができない。
参照型(String型と列挙型を除く)についても使用することができない。

fianlではない変数はcaseに使用できない

fianlではない変数はcaseに使用できない
int target = 100;
int a = 10;
final int B = 10;

switch (target) {
    case B:
        // 処理
        break;
    case a: // コンパイルエラー
        // 処理
        break;
}

配列

要素数は必ず右辺に書く

配列宣言時に左辺の型として使用する配列型(int[]や int[][]など)は配列オブジェクトへの参照を保持するためのものであり、配列の要素数については関与しない。

各要素については配列オブジェクトが管理を行う。

要素数は必ず右辺に書く
int[] array = new int[10];

// コンパイルエラー
int[10] array = new int[];

// コンパイルエラー
int[10] array = new int[10];

[]は変数名の後ろにも置ける

[]は変数名の後ろにも置ける
int[] array = new int[10];

int array2[] = new int[10];

int array3[][] = new int[10][20];

多次元配列は[]をデータ型の後ろと変数名の後ろに分散して置ける

多次元配列は[]をデータ型の後ろと変数名の後ろに分散して置ける
int[] array2[] = new int[10][20];  // 2次元配列

int[][] array3[] = new int[10][20][30]; // 3次元配列

多次元配列の1次元目の要素数は省略できない

多次元配列の1次元目の要素数は省略できない
int[][] array = new int[10][20];

int[][] array2 = new int[10][];

// コンパイルエラー
int[][] array3 = new int[][20];        

多次元配列の2次元目以降は要素数を揃える必要はない

多次元配列の2次元目以降は要素数を揃える必要はない
int[][] array = new int[3][];

array[0] = new int[10];
array[1]= new int[20];
array[2] = new int[30];

配列の初期子{}を使用する場合、要素数は指定できない

配列の初期子{}を使用する場合、要素数は指定できない
int[] array = {1, 2, 3, 4, 5};

int[] array2 = new int[]{1, 2, 3, 4, 5};

// コンパイルエラー
int[] array3 = new int[5]{ 1, 2, 3, 4, 5};

明示的に初期化しなかった配列の各要素は、型のデフォルト値になる

明示的に初期化しなかった配列の各要素は、型のデフォルト値になる
int[] a = new int[1];
System.out.println(a[0]);
// >> 0

double[] b = new double[1];
System.out.println(b[0]);
// >> 0.0

boolean[] c = new boolean[1];
System.out.println(c[0]);
// >> false

char[] d = new char[1];
System.out.println(d[0]); // \u0000
System.out.println((int)d[0]);
// >> �
// >> 0

String[] e = new String[1];
System.out.println(e[0]);
// >> null

Object[] f = new Object[1];
System.out.println(f[0]);
// >> null

コンストラクタ

コンストラクタに見えるメソッド

コンストラクタに見えるメソッド
class MyClass {
    // 戻り値を指定しているためコンストラクタ扱いにならず、メソッド扱いになる
    void MyClass(){
        System.out.println("hello world");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass a = new MyClass();
        a.MyClass();
        // >> hello world
    }
}

自身のコンストラクタはthis()で呼び出せる

自身のコンストラクタはthis()で呼び出せる
class MyClass {
    MyClass() {
        this(10);
    }

    MyClass(int a) {
    
    }
}

自身のコンストラクタを呼び出す場合、thisより前に処理は実行できない

自身のコンストラクタはthisで呼び出せる
class MyClass {
    MyClass() {
        // thisは最初に実行しなければならない
        System.out.println("hello world");
        // コンパイルエラー
        this(10);
    }

    MyClass(int a) {
    
    }
}

インターフェース

finalかつstaticなフィールドなら定義できる

finalかつstaticなフィールドなら定義できる
interface MyInterface {
    public static final int A_MAX = 10;
}

以下のように記述することも可能。

interface MuInterface {
    // 内部的には public static final int A_MAX = 10; として扱われる
    int A_MAX = 10;
}

staticなメソッドも定義できる

staticなメソッドも定義できる
interface MyInterface {
    public static void myMethod(){
        
    };
}

privateなメソッドも定義できる

privateなメソッドも定義できる
public interface MyInterface {
    private void method() {
        System.out.println("hello world");
    }
}

複数のdefaultメソッドの共通処理をまとめる事ができる。

Objectクラスのメソッドをオーバーライドできない

インターフェースは通常、中身のない抽象メソッドのみが定義可能であり、中身のあるメソッドを定義する場合defaultを使用する必要がある。

interface MyInterface {
    public void myMethodA();

    default public void myMethodB() {
        System.out.println("hello world");
    }

    // コンパイルエラー
    public void myMethodC() {
        System.out.println("hello world");
    }
}

このdefaultを使用してメソッドの定義をするとき、java.lang.Objectのメソッド(equals(), hashCode(), toString())をオーバーライドすることはできない。

Objectクラスのメソッドをオーバーライドできない
interface MyInterface {
    // コンパイルエラー
    @Override
    default public String toString() {
        return "hello world";
    }
}

インターフェースのdefaultメソッドを呼び出す

次の構文でインターフェースのdefaultメソッドを実装クラスから呼び出す事ができる。

インターフェース名.super.メソッド名()
スーパークラスのdefaultメソッドを呼び出す
interface MyInterface {
    default public void a() {
        System.out.println("hello world");
    }
}

class ConcreteClass implements MyInterface {
    @Override
    public void a() {
        // インターフェース名.super.メソッド名()
        MyInterface.super.a();
        System.out.println("hello world");
    }
}

ただし、直接実装(implements)していないスーパークラスのdefaultメソッドは呼び出せない(孫から祖父母のメソッドは呼べない)。

直接実装(implements)していないスーパークラスのdefaultメソッドは呼び出せない
interface SuperInterface {
    default public void a() {
        System.out.println("hello world");
    }
}

interface SubInterface extends SuperInterface {   
}

class ConcreteClass implements SubInterface {
    @Override
    public void a() {
        // コンパイルエラー
        SuperInterface.super.a();
        System.out.println("hello world");
    }
}

「もしインターフェース名を指定しなくても良い」とすると、多重に実装(implements)したインターフェースに同じ名前のdefaultメソッドが定義されていたらどちらのメソッドかが判別できなくなってしまう。

もしインターフェース名を指定しなくてもよかったら
interface InterfaceA {
    default public void hello() {
        System.out.println("hello world");
    }
}

interface InterfaceB {
    default public void hello() {
        System.out.println("hello world");
    }
}

class ConcreteClass implements InterfaceA, InterfaceB {
    @Override
    public void hello() {
        // コンパイルエラー(どっちのhello()?)
        super.hello();
        System.out.println("hello world");
    }
}

defaultメソッド > 通常メソッド

インタフェースの本来の目的は「型を提供すること」であり、defaultメソッドはあくまでもオプション的な位置付けであるため、同じ名前のメソッドがインターフェースとスーパークラス両方で定義されている場合、スーパークラスのメソッドが優先される。

public interface MyInterface {
    default void method() {
        System.out.println("インターフェース");
    }
}
public class SuperClass {
    public void method() {
        System.out.println("スーパークラス");
    }
}
public class MyClass extends SuperClass implements MyInterface {}
MyClass obj1 = new MyClass();
obj1.method();
// >> スーパークラス

SuperClass obj2 = new MyClass();
obj2.method();
// >> スーパークラス

MyInterface obj3 = new MyClass();
obj3.method();
// >> スーパークラス

継承

サブクラスではスーパークラスのフィールド名と同じフィールド名を使える

サブクラスではスーパークラスのフィールド名と同じフィールド名を使える。(オーバーライドではなく、実際には新しいフィールドが追加される)

ただし、実行時どちらにアクセスされるかは変数の宣言型に依存する。スーパークラス型で宣言した変数を通してアクセスを行った場合にはスーパークラスで宣言したフィールドが使用される。

同じ名前のフィールドが存在する場合
class SuperClass {
    String a = "super";
}

class SubClass extends SuperClass {
    String a = "sub";
}
実行時のアクセスは変数の宣言型に依存する
SuperClass obj1 = new SubClass();
System.out.println(obj1.a);
// >> super

SubClass obj2 = new SubClass();
System.out.println(obj2.a);
// >> sub

メソッドからのアクセスの場合、以下のようになる。

メソッドを通じたアクセス ~パターン1~
class SuperClass {
    String a = "super";

    public void b() {
        System.out.println(a);
    }
}

class SubClass extends SuperClass {
    String a = "sub";
}
メソッドの所有者のフィールドが使用される ~パターン1~
SuperClass obj1 = new SubClass();
obj1.b();
// >> super

SubClass obj2 = new SubClass();
obj2.b();
// >> super
メソッドを通じたアクセス ~パターン2~
class SuperClass {
    String a = "super";

    public void b() {
        System.out.println(a);
    }
}

class SubClass extends SuperClass {
    String a = "sub";

    // オーバーライドしている
    @Override 
    public void b() {
        System.out.println(a);
    }
}
メソッドの所有者のフィールドが使用される ~パターン2~
SuperClass obj1 = new SubClass();
obj1.b(); // オーバーライドしているためSubClassのメソッドが使用される
// >> sub

SubClass obj2 = new SubClass();
obj2.b();
// >> sub

スーパークラスのコンストラクタはコンパイル時に自動で追加される

スーパークラスのコンストラクタはコンパイル時に自動で追加される
class SuperClass {
    public SuperClass() {
        System.out.println("super class constructor");
    }
}

class SubClass extends SuperClass {
    public SubClass() {
        // コンパイル時にここに super(); が自動挿入される
        System.out.println("sub class constructor");
    }
}
SuperClass obj = new SubClass();
// >> super class constructor
// >> sub class constructor

継承させたくないクラスはfinalで修飾する

継承させたくないクラスは final で修飾する
final class myClass {
    
} 

Objectequals()

Objectequals()はオーバーライドして同値性を検証させるものだが、オーバーライドをしなかった場合には同一性==と同じ)を検証するようになっている。

staticメソッドはオーバーライドできない

staticメソッドはオーバーライドできない
public class SuperClass {
    static void method() {
    }
}
public class SubClass extends SuperClass {
    // コンパイルエラー
    @Override
    static void method() {
    }
}

ただし@Overrideアノテーションをつけなかった場合、スーパークラスのstaticメソッドを隠蔽したことになり、コンパイルエラーが起きない。

public class SubClass extends SuperClass {
    // 親クラスのメソッドを隠蔽
    static void method() {
    }
}

関数型インターフェース・ラムダ式

基本事項はこちら。

ラムダ式内で利用するローカル変数は実質的にfinalでなければならない

ラムダ式は宣言場所と同じスコープを持つため、ラムダ式内でラムダ式を宣言したスコープからアクセス可能なローカル変数にアクセスすることができる。

一方で、ラムダ式が実行されるのは宣言場所と別のタイミングになるため、ラムダ式内でローカル変数へのアクセスを行うと、そのローカル変数は実質的にfinal(effectively final)でなければならなくなる。

ラムダ式内で利用するローカル変数は実質的にfinalでなければならない
String a = "hello";

// ラムダ式内で a を参照
Runnable runnable = () -> System.out.println(a);

// aに再代入しようとするとコンパイルエラーが起きる
a = "Goodbye";

runnable.run();

関数型インターフェース 早見表

インターフェース名 定義 補足
Supplier<T> T get();
Consumer<T> void accept(T t);
BiConsumer<T, U> void accept(T t, U u);
Predicate<T> bolean test(T t);
BiPredicate<T, U> boolean test(T t, U u);
Function<T> R apply(T t);
BiFunction<T, U> R apply(T t, U u);
UnaryOperator<T> T apply(T t);
BinaryOperator<T> T apply(T t1, T t2); BiFunction<T, U>TUが同じパターン。
BiFunction<T, U>の特殊系と言う位置づけ。
Runnabale void run();
Callable<V> V call();

コレクション

Arrays.asList()が返すListは固定サイズ

配列をListに変換することができるArrays.asList()が返すListは、要素数が固定の特殊なListになっている。

通常のListと同じだと勘違いして要素を追加しようとすると、実行時例外が発生する。

Arrays.asList() が返す List は固定サイズ
List<String> list = Arrays.asList(new String[]{"aaa", "bbb", "ccc"});
list.add("ddd"); // 実行時例外が発生する

要素数が固定のListは明示的に生成することも可能。

List<String> list = new ArrayList<>();
list.add("aaa");
list.add("bbb");
list.add("ccc");

// 要素数が固定のListに変換
List<String> list2 = Collections.unmodifiableList(list);

list2.add("ddd"); // 実行時例外が発生する

動的サイズのArrayListを初期化したい場合、ArrayListのコンストラクタに固定サイズのListを渡す。

List<String> list = new ArrayList<>(
        Arrays.asList(new String[]{"aaa", "bbb", "ccc"})
);
list.add("ddd");

並列処理

暗記系クラス名とメソッド名

Executor.png

API

累乗はpow、平方根はsqrt

pow : power(累乗)

power(累乗)
// x の y 乗
Math.pow(x, y)

sqrt: square root(平方根)

square root(平方根)
// x の平方根
Math.sqrt(x)

try-catch / try-with-resources

catchfinallyブロックでどちらも戻り値をreturnしたときはfinallyの戻り値が優先される

catchとfinallyブロックでどちらも戻り値をreturnしたときはfinallyの戻り値が優先される
String a() {
    try {
        throw new Exception();
    } catch (Exception e) {
        return "catch";
    } finally {
        return "finally";
    }
}

System.out.println(a());
// >> finally

tryブロックで宣言した変数はfinallyブロックからアクセスできない

try ブロックで宣言した変数は finally ブロックからアクセスできない
try (FileInputStream is = new FileInputStream("sample.txt")) {
            
} catch (Exception e) {
    
} finally {
    // コンパイルエラー
    if (is != null) {
    }
}

リソースのクローズ時の実行順

リソース
class MyResource implements AutoCloseable {
    @Override
    public void close() {
        System.out.println("①close()が実行される");
    }
}
リソースのクローズ時の実行順
try (MyResource r = new MyResource()) {
    throw new Exception();
} catch (Exception e) {
    System.out.println("②catchブロックが実行される");
} finally {
    System.out.println("③finallyブロックが実行される");
}

// >> ①close()が実行される
// >> ②catchブロックが実行される
// >> ③finallyブロックが実行される

参考

徹底攻略Java SE 11 Gold問題集[1Z0-816]対応

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?