Javaの言語仕様で忘れがちなこと
近々Java Silverの資格試験を受けるということで自分が覚えてない or 間違えやすいことについてまとめます。
アンダースコアを使った整数リテラル
- リテラルの先頭と末尾には使用できない。
- 記号(. , L , F0b, 0x etc.)の前後には記述できない。8進数を表す0の前後はOK。
int a = 1_200_0;
int b = 0_7145;
char型変数に代入することができるリテラル
- 文字リテラル(シングルクオーテーションで囲う)。
- シングルクオーテーションで囲った\uから始まるUnicode番号(16進数4桁)
- 0から65535までの数値リテラル。
char a = 'a';
char b = '\u1111';
char c = 65535;
識別子の命名規則
- 予約語は使えない。
- 使える記号はアンダースコアと通貨記号のみ。
- 数字から始めてはいけない。
int a1;
int $a;
int _a;
型推論のルール
- 初期化必須。null初期化不可。
- 配列の初期化式不可。
- ArrayListは可。
- メソッドの引数不可。
var a = new ArrayList<> //Object型で初期化される。
mutableなクラスのキャパシティ
- ArrayListの初期キャパシティは10
- StringBuilderの初期キャパシティは初期化された文字数+16
switch文
switch文の条件式が戻せる型
- int型以下の整数型とそのラッパークラス
- 文字と文字列
- 列挙型
case値として使用できる値の条件
- 条件式が戻す値と同じ型か互換性がある型
- 定数であるか、コンパイル時に値を決めることができること
- nullでないこと
for文の初期化文、条件文、更新文
- 複数の文を記述できるのは初期化式と更新文のみ、 ”, "で区切って複数記述できる。
- 条件文は論理演算する必要がある。
for(i=0, j=0; i<5 || j<4; i++, j++){
配列型変数
宣言
- データ型の後ろ
- 変数名
- 上記両方
- 宣言時変数の[]に要素数の指定は不可。
int[] a; //1次元配列
int a[]; //1次元配列
int a[][]; //2次元配列
int[] a[]; //2次元配列
配列オブジェクトの生成方法
- newによるオブジェクト生成時は要素数の指定が必要。
- int型による要素数の指定が必要。
- 多次元配列の場合、最低1次元目のみ要素数の指定が必要。
int[] a = new a[3];
int[][] b = new a[2][];
初期化
- 初期化子( {} )を使うと、配列オブジェクトの生成と初期化、参照の代入を一気に行うことができる。
- 初期化子はnewと一緒に使うこともできる。
- 初期化子をnewと同時に使う場合、要素数は自動計算される。[]の要素数を記述してはいけない。
- 初期化子とnewを同時に使う場合、変数で定義された次元数とあった[]を記述する必要がある。
- 初期化子を使う場合、次元数がわかる表記が同じ文中に存在する必要がある。基本的に宣言と分けて初期化子を使わないほうがわかりやすい。
int a[] = new int[3];
int b[] = {1,2,3};
int d[] = new int[]{1,2,3};
int e[] = new int[]{};
int f[][] = new int[][]{}
int g[];
g = new int[]{1,2,3};
可変長引数
- 可変長引数は配列と同様のアクセスができる。
- 引数の型のと直後に...を記述
- 可変長引数以外の引数を受け取る場合、可変長引数を最後の引数にする。
void method1(int... num){};
void method2(String text, int... num){};
到達不可能なコード
到達不可能なコードを書くと普通にコンパイルエラーになる。
初期化子、static初期化子
- 初期化子を使うとコンストラクタが実行される前に処理を実行できる。
- クラスブロック直下に記述する。
- static初期化子を使うことでstaticなフィールドの設定も可能。
public class Test{
{
//do something
}
デフォルトコンストラクタ
- デフォルトコンストラクタはコンストラクタを明示的に定義しないときにのみ自動的に追加される。
コンストラクタの呼び出し
- コンストラクタ内でthisを使ってコンストラクタを呼び出す場合、先頭に記述する必要がある。
public class Test{
public Test(){
this("test1");
System.out.println("test2");
}
public Test(String str){
System.out.println(str);
}
}
インターフェースでのオーバーライド
- Objectクラスメソッドのオーバーライドはコンパイルエラーになる。
- デフォルトメソッドをオーバーライドしたメソッドからデフォルトメソッドを呼び出す場合、インターフェース名.super.メソッド名で呼び出す。
- 二つ以上の実現や継承の改装をまたいで呼び出しはできない。
interface A {
default void a(){
//do something
}
}
interface B extends A {
default void b(){
//do something
}
}
public class Test implements B{
B.super.b(); //Aは呼び出すことができない
}
オーバーライドの条件
- シグニチャが同じであること(メソッド名、引数リストの型、数、順番)
- 戻り値は強制戻り値を使うことで、サブクラスの型を戻すメソッドをオーバーライドとして使うことができる。
- インターフェースで宣言されている抽象メソッドは必ずしも実装先で実装される必要はない。継承先で実装関係になくても、同じシグニチャのメソッドが宣言されている場合、実装されていると判断される。