(注:このブログはもう更新していません)この日記は私的なものであり所属会社の見解とは無関係です。 GitHub: takahashikzn

[クラウド帳票エンジンDocurain]

Java17からは事実上、ローカル静的変数が使える

この記事を見ました。Java17 Java16から無名クラスやインナークラスでもstaticフィールドを使えるとのことです。

https://cr.openjdk.java.net/~jrose/jls/FunnyStatic.java

で思ったのですが、ならばこうすれば良いのでは…?

つまり、

class Counter {
    private static int count;
    
    public static int countup() { return count++; }
}

をこんな書き方にする。

class Counter {
    
    public static int countup() {
        final class _static_ {
            static int count;
        }


        return _static_.count++;
    }
}

試しにやって見ましたが、当然ながら問題無く動きます。

もしかして、staticメソッドに関してはもっと前のJavaのバージョンでもこのように、ローカルクラス内でstaticフィールドを使えたのかもしれませんが、 インスタンスメソッドで宣言したローカルクラスはJava16以前ではstaticフィールドを定義できなかったため、 上記の書き方に統一できるようになったのはJava16から、と理解して良いかと。

staticフィールドのスコープを定義できるためコードの可読性に寄与します。 気に入ったので積極的に使っていこうと思います。

ついでにローカルメソッドも使える

class Foo {

    // barでしか使わない
    private static int mul(int x, int y) { return x * y; }
    private static int add(int x, int y) { return x + y; }

    public static int bar(int x, int y) {
        return add(add(x, y), mul(x, y));
    }
}
class Foo {

    public static int bar(int x, int y) {
        final class _static {
            static int mul(int x, int y) { return x * y; }
            static int add(int x, int y) { return x + y; }
        }

        return _static.add(_static.add(x, y), _static.mul(x, y));
    }
}

まあこちらはローカル静的変数よりは使いどころが少ないと思いますが、 一応できると言うことで。

ちなみに

「普通の」Javaの書き方からは逸脱しているんでしょうけど僕は一切気にしません。 常識を打破する発想力は日々の積み重ねかと。