覚えたら書く

IT関係のデベロッパとして日々覚えたことを書き残したいです。twitter: @yyoshikaw

com.google.common.base.Preconditions

Guavacom.google.common.base.Preconditionsの利用サンプルです。

メソッドの引数をチェックしてNullPointerExceptionをスローさせたり、IllegalArgumentExceptionをスローさせたりすることがあると思いますが、そのような事前条件のチェックを補助してくれるメソッドを提供しています。

  • Preconditions#checkArgument
    • チェック対象の条件がNG(false)の場合はIllegalArgumentExceptionをスローします

  • Preconditions#checkNotNull
    • チェック対象の値がnullの場合はNullPointerExceptionをスローします

  • Preconditions#checkState
    • チェック対象の条件がNG(false)の場合はIllegalStateExceptionをスローします

  • Preconditions#checkElementIndex(int index, int size)
    • index < 0 or index >= size の場合にIndexOutOfBoundsExceptionをスローします

  • Preconditions#checkPositionIndex(int index, int size)
    • index < 0 or index > size の場合にIndexOutOfBoundsExceptionをスローします

  • Preconditions#checkPositionIndexes(int start, int end, int size)
    • start, end が、List#subList や String#substring などの引数として不適合の場合にIndexOutOfBoundsExceptionをスローします


Preconditions#checkArgument

  • 事前条件
    • 値が0以上であること
  • NG(false)の場合
    • IllegalArgumentExceptionをスローします

■サンプルコード

private static void function1(int arg) {
    /*
     * 以下と同等のチェック処理
     * if (arg < 0) {
     *     throw new IllegalArgumentException("引数は0以上の値を指定してください。 [arg: " + arg + "]");
     * }
     */
    Preconditions.checkArgument(arg >= 0, "引数は0以上の値を指定してください。 [arg: %s]", arg);

    System.out.println("exec function1 [My Age = " + arg + "]");
}


// OK
function1(1);

// NG
try {
    function1(-1);
} catch (IllegalArgumentException e) {
    System.out.println(e.getMessage());
}

■実行結果

exec function1 [My Age = 1]
引数は0以上の値を指定してください。 [arg: -1]


Preconditions#checkNotNull

  • 事前条件
    • 値がnullでないこと
  • NG(false)の場合
    • NullPointerExceptionをスローします

■サンプルコード

private static void function2(String arg) {
    /*
     * 以下と同等のチェック処理
     * if (arg == null) {
     *     throw new NullPointerException("引数がnullです。");
     * }
     */
    String validValue = Preconditions.checkNotNull(arg, "引数がnullです。");

    System.out.println("exec function2 [UppderCase: " + validValue.toUpperCase() + "]");
}


// OK
function2("Jon");

// NG
try {
    function2(null);
} catch (NullPointerException e) {
    System.out.println(e.getMessage());
}

■実行結果

exec function2 [UppderCase: JON]
引数がnullです。


Preconditions#checkState

  • 事前条件
    • x > 0, y > 0 であること
  • NG(false)の場合
    • IllegalStateExceptionをスローする

■サンプルコード

private static void function3(double x, double y) {
    // 0での除算を避けるため、0以上である事をチェックする
    Preconditions.checkState(x > 0 && y > 0, "x or y is invalid.");

    System.out.println("exec function3 [x / y = " + (x / y) + ", y / x = " + (y / x) + "]");
}


// OK
function3(8, 4);

// NG
try {
    function3(100, 0);
} catch (IllegalStateException e) {
    System.out.println(e.getMessage());
}

■実行結果

exec function3 [x / y = 2.0, y / x = 0.5]
x or y is invalid.


Preconditions#checkElementIndex, Preconditions#checkPositionIndex

  • 事前条件
    • startIdx: 0~9, endIdx: 0~10 であること
  • NG(false)の場合
    • IndexOutOfBoundsExceptionをスローする

■サンプルコード

private static void function4(int startIdx, int endIdx) {
    final String src = "HelloWorld";

    Preconditions.checkElementIndex(startIdx, src.length());
    Preconditions.checkPositionIndex(endIdx, src.length());

    String subStr = src.substring(startIdx, endIdx);
    System.out.println("exec function4 [" + src + ".substring(" + startIdx + ", " + endIdx + ") -> " + subStr + "]");
}


// OK
function4(0, 5);
function4(9, 10);
function4(0, 0);

// NG
try {
    function4(-1, 5);
} catch (IndexOutOfBoundsException e) {
    System.out.println("function4(-1, 5) Index failed.: " + e.getMessage());
}

try {
    function4(10, 10);
} catch (IndexOutOfBoundsException e) {
    System.out.println("function4(10, 10) Index failed.: " + e.getMessage());
}

try {
    function4(5, 11);
} catch (IndexOutOfBoundsException e) {
    System.out.println("function4(5, 11) Index failed.: " + e.getMessage());
}

■実行結果

exec function4 [HelloWorld.substring(0, 5) -> Hello]
exec function4 [HelloWorld.substring(9, 10) -> d]
exec function4 [HelloWorld.substring(0, 0) -> ]
function4(-1, 5) Index failed.: index (-1) must not be negative
function4(10, 10) Index failed.: index (10) must be less than size (10)
function4(5, 11) Index failed.: index (11) must not be greater than size (10)


Preconditions#checkPositionIndexes

  • チェックする事前条件
    • startIdxとendIdxがList#subListの引数として問題ない値範囲であること
  • NG(false)の場合
    • IndexOutOfBoundsExceptionをスローする

■サンプルコード

private static void function5(int startIdx, int endIdx) {
    final List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j");

    Preconditions.checkPositionIndexes(startIdx, endIdx, list.size());

    List<String> subList = list.subList(startIdx, endIdx);
    System.out.println("exec function5 [list.subList(" + startIdx + ", " + endIdx + ") -> " + subList + "]");
}


// OK
function5(0, 10);
function5(0, 0);
function5(0, 5);
function5(2, 3);
function5(8, 10);
function5(10, 10);

// NG
try {
    function5(-1, 4);
} catch (IndexOutOfBoundsException e) {
    System.out.println("function5(-1, 4) Index failed.: " + e.getMessage());
}

try {
    function5(6, 11);
} catch (IndexOutOfBoundsException e) {
    System.out.println("function5(6, 11) Index failed.: " + e.getMessage());
}

try {
    function5(11, 20);
} catch (IndexOutOfBoundsException e) {
    System.out.println("function5(11, 20) Index failed.: " + e.getMessage());
}

try {
    function5(5, 3);
} catch (IndexOutOfBoundsException e) {
    System.out.println("function5(5, 3) Index failed.: " + e.getMessage());
}        

■実行結果

exec function5 [list.subList(0, 10) -> [a, b, c, d, e, f, g, h, i, j]]
exec function5 [list.subList(0, 0) -> []]
exec function5 [list.subList(0, 5) -> [a, b, c, d, e]]
exec function5 [list.subList(2, 3) -> [c]]
exec function5 [list.subList(8, 10) -> [i, j]]
exec function5 [list.subList(10, 10) -> []]
function5(-1, 4) Index failed.: start index (-1) must not be negative
function5(6, 11) Index failed.: end index (11) must not be greater than size (10)
function5(11, 20) Index failed.: start index (11) must not be greater than size (10)
function5(5, 3) Index failed.: end index (3) must not be less than start index (5)



試したソースコードの全体は以下の通りです

import java.util.Arrays;
import java.util.List;

import com.google.common.base.Preconditions;

public class PreconditionsClient {

    public static void main(String[] args) {

        System.out.println("### Preconditions.checkArgument execute.");
        function1(1);

        try {
            function1(-1);
        } catch (IllegalArgumentException e) {
            System.out.println(e.getMessage());
        }

        System.out.println("\n### Preconditions.checkNotNull execute.");
        function2("Jon");

        try {
            function2(null);
        } catch (NullPointerException e) {
            System.out.println(e.getMessage());
        }

        System.out.println("\n### Preconditions.checkState execute.");
        function3(1, 5);

        try {
            function3(100, 0);
        } catch (IllegalStateException e) {
            System.out.println(e.getMessage());
        }

        System.out.println("\n### Preconditions.checkElementIndex, checkPositionIndex execute.");
        function4(0, 5);
        function4(9, 10);
        function4(0, 0);

        try {
            function4(-1, 5);
        } catch (IndexOutOfBoundsException e) {
            System.out.println("function4(-1, 5) Index failed.: " + e.getMessage());
        }

        try {
            function4(10, 10);
        } catch (IndexOutOfBoundsException e) {
            System.out.println("function4(10, 10) Index failed.: " + e.getMessage());
        }

        try {
            function4(5, 11);
        } catch (IndexOutOfBoundsException e) {
            System.out.println("function4(5, 11) Index failed.: " + e.getMessage());
        }


        System.out.println("\n### Preconditions.checkPositionIndexes execute.");
        function5(0, 10);
        function5(0, 0);
        function5(0, 5);
        function5(2, 3);
        function5(8, 10);
        function5(10, 10);

        try {
            function5(-1, 4);
        } catch (IndexOutOfBoundsException e) {
            System.out.println("function5(-1, 4) Index failed.: " + e.getMessage());
        }

        try {
            function5(6, 11);
        } catch (IndexOutOfBoundsException e) {
            System.out.println("function5(6, 11) Index failed.: " + e.getMessage());
        }

        try {
            function5(11, 20);
        } catch (IndexOutOfBoundsException e) {
            System.out.println("function5(11, 20) Index failed.: " + e.getMessage());
        }

        try {
            function5(5, 3);
        } catch (IndexOutOfBoundsException e) {
            System.out.println("function5(5, 3) Index failed.: " + e.getMessage());
        }

    }

    /**
     * 事前条件:引数が0以上である事
     */
    private static void function1(int arg) {
        /*
         * 以下と同等のチェック処理
         * if (arg < 0) {
         *     throw new IllegalArgumentException("引数は0以上の値を指定してください。 [arg: " + arg + "]");
         * }
         */
        Preconditions.checkArgument(arg >= 0, "引数は0以上の値を指定してください。 [arg: %s]", arg);

        System.out.println("exec function1 [My Age = " + arg + "]");
    }

    /**
     * 事前条件:指定の値がnullでない事
     */
    private static void function2(String arg) {
        /*
         * 以下と同等のチェック処理
         * if (arg == null) {
         *     throw new NullPointerException("引数がnullです。");
         * }
         */
        String validValue = Preconditions.checkNotNull(arg, "引数がnullです。");

        System.out.println("exec function2 [UppderCase: " + validValue.toUpperCase() + "]");
    }

    /**
     * 事前条件:x > 0, y > 0 であること
     */
    private static void function3(int x, int y) {
        // 0での除算を避けるため、0以上である事をチェックする
        Preconditions.checkState(x > 0 && y > 0, "x or y is invalid.");

        System.out.println("exec function3 [x / y = " + (x / y) + ", y / x = " + (y / x) + "]");
    }

    /**
     * 事前条件:startIdx: 0~9, endIdx: 0~10
     */
    private static void function4(int startIdx, int endIdx) {

        final String src = "HelloWorld";

        Preconditions.checkElementIndex(startIdx, src.length());
        Preconditions.checkPositionIndex(endIdx, src.length());

        String subStr = src.substring(startIdx, endIdx);
        System.out.println("exec function4 [" + src + ".substring(" + startIdx + ", " + endIdx + ") -> " + subStr + "]");
    }

    /**
     * 事前条件:startIdxとendIdxがList#subListの引数として問題ない値範囲であること
     */
    private static void function5(int startIdx, int endIdx) {

        final List<String> list = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j");

        Preconditions.checkPositionIndexes(startIdx, endIdx, list.size());

        List<String> subList = list.subList(startIdx, endIdx);
        System.out.println("exec function5 [list.subList(" + startIdx + ", " + endIdx + ") -> " + subList + "]");
    }
}