頭脳一式

人の記憶なんて曖昧なもの。すべての情報を頭に記憶するなんてナンセンス。困ったらここに来ればいいじゃん?

【Java SE8 Silver】プリミティブ型と参照型の違い。wrapperクラスとは

プリミティブ型はint,char,booleanなど。
参照型はオブジェクト型、列挙型、配列型がある。

プリミティブ型の変数は値を保持するものだからnullは代入できない。
プリミティブ型の変数は値そのものを保持する。
参照型の変数はオブジェクトへの参照(リンク)を保持する。

プリミティブ型(基本データ型) wrapperクラス superクラス
boolean Boolean Object
char Character Object
byte Byte Number
short Short Number
int Integer Number
long Long Number
float Float Number
double Double Number

wrapperクラスとは

プリミティブ型をラップするクラスの総称。
プリミティブ型と対応するラッパークラスのオブジェクトを作成し、
そのオブジェクトに対して用意されたメソッドを利用することでプリミティブ型の値を操作することができる。

wrapperクラスの特徴はキャスト宣言せずにプリミティブ型に戻せること。
この仕組を「オートボクシング」と呼ぶ。
以下の両パターンが書ける。

int i2  = (int) Integer.valueOf("100");
int i3  = Integer.valueOf("100");//キャストを省略できる。

【Java SE8 Silver】配列の宣言と配列インスタンスの生成

Javaの配列はややこしいのでまとめてみる。

配列の宣言方法

配列の宣言には大カッコを使う。
データ型の後ろに記述するパターンと変数名の後ろに記述するパターンの2通りある。

int[] array;//データ型の後ろに大カッコを記述するパターン。
int array[]://変数名の後ろに大かっこを記述するパターン。

多次元配列の場合は、大カッコの数で次元数を表す。

int[][] arrayA;//2次元配列の宣言
int arrayB[][][];//3次元配列の宣言

また、多次元配列の場合は、大カッコを一度にまとめて記述する必要は無く、データ型と変数名の後ろに分けて記述することができる。

int[] arrayA[];//1+1で2次元配列の宣言
int[][] arrayB[];//2+1で3次元配列の宣言

配列インスタンスの生成方法

配列インスタンスの生成には以下の制約がある。

  • 配列インスタンスの生成には必ず要素数を指定すること。
  • 素数の指定はint型の整数値でなければならず、
    浮動小数点や、整数値であってもlong型は記述できないこと。
  • 多次元配列の場合は、変数の次元数と参照先の次元数が一致すること。

以下はコンパイルエラー

int[] arrayA = new int[];//要素数がないのでコンパイルエラー
int[] arrayB = new int[2.3];//浮動小数点を記述しているのでコンパイルエラー
int[][] arrayC = new int[]{};//次元数が一致してないのでコンパイルエラー。

1次元目の要素数は省略できない。が、2次元目の要素数を省略して別々のタイミングで生成することが可能。
データ型に書くは要素数を表し、変数に書くは添字を表す。

int[][] arrayA = new array[3][];//2次元目の要素数が無くても可。
array[0] = new int[3];
array[1] = new int[3];
array[2] = new int[3];

int[][] arrayB = new array[][3];//1次元目の要素数がない場合はコンパイルエラー。

配列インスタンスの生成と同時に要素の値を初期化したい場合は、初期化演算子{}を使う。

int[] arrayA = new int[] {10,20,30};//パターン1
int[] arrayB = {10,20,30};//パターン2

newと初期化演算子の両方を使った場合は、要素数を指定することはできない。
なぜなら初期化演算子の中に記述した値の数によって自動的に配列の要素数が決まるから 。
次のように記述するとコンパイルエラーとなる。

int[] array = new int[3] {10,20,30};//要素数を指定するとコンパイルエラー。
素数0の配列。

インスタンス的には何の意味も無いが、文法上間違っているわけではないのでコンパイルが通る。
以下の書き方はどれも同じ意味になる。

int[] arrayA = {};
int[] arrayC = new int[0];

【Java SE8】関数型インターフェースとは

関数型インターフェースとは、抽象メソッドを1つ持っているインターフェースのこと。
Objectクラスからオーバーライドしたメソッドや、defaultメソッド、staticメソッドの実装が含まれていても
抽象メソッドが1つ定義されていれば、関数型インターフェースとして認識される。
関数型インターフェースとして定義出来ているかどうかを確認するには「@FunctionalInterface」を用いる。

関数型インターフェースとして定義できている例1)

抽象メソッドが1つのみのパターン。

@FunctionalInterface
public interface IF {
    public void Ex1(String str);
}

関数型インターフェースとして定義できている例2)

抽象メソッド、ObjectクラスのからオーバーライドしたtoString()メソッド、defaultメソッドの組合せ。

@FunctionalInterface
public interface IF {
    public void Ex1(String str);
    public String toString();
    default void Ex2() {}
}

関数型インターフェースとして定義できていない例1)

抽象メソッドが1つもないパターン。

@FunctionalInterface
public interface IF {    //ここでコンパイルエラー。
    public String toString();
    default void Ex2() {}
}

関数型インターフェースとして定義できていない例2)

抽象メソッドを2つ以上定義したパターン。

@FunctionalInterface
public interface IF {    //ここでコンパイルエラー。
    public void Ex1(String str);
    public void Ex2(String str);

}

関数型インターフェースの実装

@FunctionalInterface
interface IF {
    void add(int x,int y);
}

//普通に実装するとこうなる。
@Override
public void add(int x,int y){
  System.out.println(x + y);
}

//ラムダ式で書くとこうなる。
IF IF1 = (x,y) -> System.out.println(x + y);
IF1.add(5,3);

【Java】Junitのアノテーションとアサーション

まずはアノテーションの説明から。

アノテーション 意味
@BeforeClass テストクラスの開始時に1度だけ実行されるメソッドであることを明示的に示す。
デフォルトはsetUpBeforeClassメソッド。
@AfterClass テストクラスの終了時に1度だけ実行されるメソッドであることを明示的に示す。
デフォルトはtearDownAfterClassメソッド。
@Before 各テストメソッドが呼び出される前に実行されるメソッドであることを明示的に示す。
デフォルトはsetupメソッド。
@After 各テストメソッドの終了後に実行されるメソッドであることを明示的に示す。
デフォルトはtearDownメソッド。
@Test テストメソッドであることを明示的に示す。
@Ignore テストメソッドから除外することを明示的に示す。

注意すべき要点は以下。

  • 「@BeforeClass」と「@AfterClass」はテストクラスの開始時と終了時に1度だけ実行される。
  • 「@Before」と「@After」は各テストメソッドの開始時と終了時に呼ばれる。(テストメソッドの数だけ実行される。)
  • テストメソッド名の頭に「test」を付けなくても「@Test」を付けることでテストメソッド扱いにできる。

こんなことしか思いつかないけど凄く役に立ちそう。
「@BeforeClass」と「@AfterClass」の使用例

@BeforeClass
public static void setUpBeforeClass() throws Exception {
  //データベースに接続
}

@AfterClass
public static void tearDownAfterClass() throws Exception {
  //データベース接続の切断
}

「@Before」と「@After」の使用例

static int testNo = 1;

@Before
public void setUp(){
    System.out.println("テストNo"+testNo+"開始。");
}

@After
public void tearDown(){
    System.out.println("テストNo"+ testNo++ +"終了。");
}

執筆中…

【Java SE8 Silver】エラーと検査例外と非検査例外

種類 意味
エラー
erroer
プログラムからは対処のしようがない事態を指す。
(実行マシンのメモリが不足していたり、ディスクの読み込み書き込み権限が無かったり…)
エラーは例外処理をすることを「求められていない」だけであって、catchして処理することが可能。
検査例外
Exception
例外処理を記述したかどうかをコンパイラ検査する例外を指す。
非検査例外
RuntimeException
及びそのサブクラス
例外処理を記述したかどうかをコンパイラ検査しない例外を指す。

Exceptionクラスのサブクラスは、RuntimeExceptionとそのサブクラスを除いてすべて検査例外である。
そのため、Exceptionクラスを継承している例外クラスは、
try-catchしているかthrows句で宣言しているかのどちらかを強制される。
一方、ExceptionクラスのサブクラスであってもRuntimeExceptionとそのサブクラスは
非検査例外として扱われる。そのため、try-catchしているかthrows句で宣言しているかを強制されない。
(宣言してもしてなくても可)

種類 意味
ArrayIndexOutOfBoundsException 配列の要素外にアクセスしたときに発生する表す例外クラス。
IndexOutOfBoundsException 存在しない要素を取り出そうとしてたときに発生する例外クラス。
StringIndexOfBoundsException 文字列の範囲外アクセスを表す例外クラス。
ClassCastException 継承関係や実現関係に無いクラスにキャストしようとしたとき発生する例外クラス。
IllegalArgumentException 利用される側のオブジェクトが不正な引数を渡されたことを、利用する側のオブジェクトに通知するための例外。
IllegalStateException 利用される側のオブジェクトが、まだ利用するための準備が終わっていないなどの理由でスローする例外。
NumberFormatException 数値に変換しようとして失敗したときにスローされる例外。
ExceptionInInitializerError staticイニシャライザを処理している間にトラブルが発生したときに強制終了させるためのエラー。
StackOverflowErro 再帰処理をしているとスタック領域が足りなくなってくる。JVMが足りないことを検知したときに発生するエラー。
NoClassDefFoundError JVMが実行対象のクラスファイルを発見できなかったときにスローする例外。
OutOfMemoryError ヒープ領域が足りなくなったときにスローする例外。
VirtualMachineError 「OutOfMemoryError」や「StackOverflowErro」の親クラス。
JVMが壊れているか、または動作を継続するのに必要なリソースが足りなくなったときにスローする例外。
InternalErro 「VirtualMachineError」のサブクラス。
JVM内で何らかの内部エラーが発生したことを指す。

shell

よく使うコマンドと多すぎて覚える気の起きないオプションについてのまとめ。

■演算比較

if文やwhile文の条件で、変数等を数値として評価して比較を行いたい場合は、以下のように記述する。

評価式 意味
数値1 -eq 数値2 数値1と数値2が等しい場合に真(=)
数値1 -ne 数値2 数値1と数値2が等しくない場合に真(!=)
数値1 -gt 数値2 数値1より数値2の方が大きい場合に真(超過)
数値1 -lt 数値2 数値1が数値2より小さい場合に真(未満)
数値1 -ge 数値2 数値1が数値2より大きいか等しい場合に真(以上)
数値1 -le 数値2 数値1が数値2より小さいか等しい場合に真(以下)

■ファイルチェック

if文やwhile文の条件で、ファイルの形式・パーミッション・特性を評価したい場合は以下のように記述する。

評価式 意味
-d path ディレクトリであれば真
-f path ファイルであれば真
-e path ファイルが存在すれば真
-L path シンボリックリンクであれば真
-r path 読取り可能ファイルであれば真
-w path 書き込み可能ファイルであれば真
-x path 実行可能ファイルであれば真
-s path ファイルサイズが0より大きい場合は真
file1 -nt file2 ファイル1がファイル2より新しい場合は真
file1 -ot file2 ファイル1がファイル2より古い場合は真

■特殊変数

変数 意味
$0 スクリプトの名前返す
$1, $2, …, $9 第1引数, 第2引数, …, 第9引数
$# 与えられた引数の数
$* 与えられたすべての引数. 引数全体が"で囲まれている
$@ 与えられたすべての引数. 引数一つ一つが"で囲まれている
$- シェルに与えられたフラグ
$? 最後に行ったコマンドの戻り値
$$ 現在のシェルのプロセス番号
$! 最後にバックグラウンドで行ったコマンドのプロセス番号

デザインパターン

Singletonパターン

世の中には「世界に1つだけしか存在しないもの(2つ以上は存在しないもの)」がある。
オブジェクト指向の本質に鑑みれば「現実世界で1つだけ」のものは「JVM内の仮想世界でも1つだけであるべき」ということになる。
しかしクラスがある以上、newを行えば行った分だけインスタンスが生成されてしまう。
絶対に1回しかnewできないように、唯一無二のインスタンスを生成する手法をsingletonパターンという。

public final class singleton {
    private static singleton theInstance;    //インスタンス保持用変数
    private singleton(){}                    //プライベートコンストラクタ
    public static singleton getInstance(){    //インスタンス取得用メソッド
        if (theInstance == null){
            theInstance = new singleton();
        }
        return theInstance;
    }
}

コンストラクタがprivateになっている意味は、
「privateとは他のクラスは利用できないこと」→「このコンストラクタは他クラスから呼びだせない。」→「自身でしかnewできない。」 ということ。
他クラスはgetInstance()メソッドを呼び出すことで、戻り値としてインスタンスが取得できる仕組みになっている。
複数回getInstance()メソッドを呼び出したとしても、2回目以降は既にインスタンスがあるのでnewされず、1回目にnewしたときのインスタンスが返るようになっている。
↓↓他クラスからインスタンスを取得する記述例↓↓

singleton obj = new singleton(); //この記述はコンストラクタが不可視でコンパイルエラー。
singleton obj1 = singleton.getInstance(); //この記述でインスタンスを取得できる。  

Strategyパターン

一言でいうとクラスをプラグイン化する。
共通の抽象クラス(又はインターフェース)を持つ複数のクラスを準備しておき、どれをnewするかを状況に応じて切り替える設計のことを をStrategyパターンという。

GameMode Gm = null;
String mode = "easy";

switch (mode) {
case "easy":
    Gm = new EasyMode();
    break;

case "normal":
    Gm = new NormalMode();
    break;

case "hard":
    Gm = new HardMode();
    break;
default :
    Class<?> Class = Class.forName(mode);
    Gm = (GameMode) Class.newInstance();
}

デザインパターンFacade

Facadeと書いてファサードと読む。フランス語らしい。

執筆中…