今日のjavaおっかけ(20150414):staticインポート

今日から.java少しでもついてかないと.

目次とぶっつぶつテーマ

http://snoopopo.hatenablog.com/entry/2015/04/14/102732

今日のテーマ:staticインポート

java5から登場.

こんなstaticなクラスがあるとして…

package test.util;
public class TestUtility {
    public static final int testFinalN = 1;
    public static int testN = 2;
    public static int sum(int n, int n2){
        return n + n2;
    }
}

別パッケージのmainメソッドから呼ぶとき、今まではこんな↓感じに書いてたけど.

package main;
import test.util.TestUtility;
public class Main {
    public static void main(String[] args) {
        //従来の書き方
        TestUtility.sum(TestUtility.testN, TestUtility.testFinalN);
    }
}

staticインポートすると、こんな書き方が出来る.

package main;
import static test.util.TestUtility.sum;
import static test.util.TestUtility.testN;
import static test.util.TestUtility.testFinalN;

public class Main {
    public static void main(String[] args) {
        //staticインポートした書き方
        sum(testN, testFinalN);
    }
}

staticインポートと呼ばれるけど、構文は、import static ~ .順番注意.

staticメソッドやstaticフィールドを指定する.

もちろん普通のimport文と同じように*指定も可能.

import static test.util.TestUtility.*;

インターフェースに定義されたフィールドもstaticインポートできる.

import static test.util.ConstInterface.INTERFACE_CONST100;

ちなみにインタフェースに定数を列挙する手法はたしかに存在するけど、 Effective Java 項目19 型を定義するためだけにインタフェースを使用する ではお勧めしてない.

staticインポートは名前指定だということ

自分が意図していないメソッドをインポートしてしまいそうだと思った.

package main;
import static test.util.TestUtility.sum;
public class Main {
    public static void main(String[] args) {
        //staticインポートした書き方(int引数2つ)
        sum(testN, testFinalN);

        //staticインポートした書き方(int引数3つ)
        sum(testN, testFinalN, 1);
    }
}

たとえばオーバーロードされた(名前だけ一緒の)メソッドは、名前が一緒なので単一のメソッドをインポートしているわけではなくなる.

*じゃなくてメソッド名を指定してるから単一のメソッドかと一見思ってしまう(かも)けど 実際はそうじゃないというのは、わかりにくくないかなあ,と.

もちろん、名前かぶった別のものはコンパイルエラーになります

import static test.util.TestUtility.sum;
import static test.util.TestUtilitySecond.sum;
public class Main {
    public static void main(String[] args) {
        sum(testN, testFinalN); //コンパイルエラー!「あいまいです」
    }
}

このあたりの概念というかjava名前空間まわりの話は、

プログラミング言語Java 7.5 名前の意味 あたりに書いてくれてる.