Java のヒント: ローカル関数を使用して関数を非表示にして保護する

ある程度の開発経験のある開発者は、ローカル変数を使用し、グローバル変数の使用をできるだけ避けるようにする必要があることを知っておく必要があります。変数が公開されすぎると悪用される可能性があり、セキュリティ上の問題が発生したり、コードのメンテナンスに問題が発生したりする可能性があります (変数が多くの場所で使用されているかどうかを注意深く確認する必要があるなど)。

関数/手順/メソッドについてはどうですか?オブジェクト指向プログラミングと一部のモジュール技術の人気により、次のような関数を非表示にすることもできます。

public class Demo {
    
    
    public static void main(String[] args) {
    
    
        fun1();
    }

    private static void fun1() {
    
    
        //...
    }
}

ここでの静的メソッドfun1は、Demo クラス内でのみ使用できます。

それでも、実際の開発では、クラスのコードは数百行または数千行になる場合があるため、private メソッドの表示スコープはグローバル関数とほぼ同じになります。ただし、このメソッドは 1 か所でのみ使用される可能性が高く、その場所用にカスタマイズされた補助メソッドである可能性もあるため、このメソッドの表示範囲がクラス全体であることは不適切です。

ラムダ式を使用してメソッド内でローカル関数を定義する

JavaScript では、function を使用してローカル関数を直接定義できます。

function main(){
    
    
    function fun1(){
    
    
        //...
    }
    fun1();
}

Java はメソッド内でメソッドを直接定義できませんが、幸いなことに Java 8 ではいくつかの関数型言語から借用し、ラムダ式と関数型インターフェイスが導入されているため、Java でローカル関数を定義することもできます。これらの機能を利用すると、上記のコードは次のようになります。

class Demo {
    
    
    public static void main(String[] args) {
    
    
        Runnable fun1 = () -> {
    
    
            //....
        };
        fun1.run();
    }
}

戻り値を含むローカル関数を定義する場合は、Supplierインターフェイスを使用できます。

class Demo {
    
    
    public static void main(String[] args) {
    
    
        Supplier<Integer> fun1 = () -> {
    
    
            //....
            return 1;
        };
        Integer integer = fun1.get();
    }
}

パラメータのみを受け取り、戻り値を持たないローカル関数の場合は、Consumerインターフェイスを使用します。

class Demo {
    
    
    public static void main(String[] args) {
    
    
        Consumer<Integer> fun1 = (Integer i) -> {
    
    
            //....
        };
        fun1.accept(1);
    }
}

パラメータと戻り値の両方が必要な場合は、Functionインターフェイスを使用します。

class Demo {
    
    
    public static void main(String[] args) {
    
    
        Function<Integer, String> fun1 = (Integer i) -> {
    
    
            //....
            return "number:" + i;
        };
        String s = fun1.apply(1);
    }
}

複数のパラメータがある場合は、独自の関数インターフェイスを定義できます。

interface Fun2<A, B, C> {
    
    
    C apply(A a, B b);
}

class Demo {
    
    
    public static void main(String[] args) {
    
    
        Fun2<Integer, String, String> fun1 = (Integer i, String s) -> {
    
    
            //....
            return s + i;
        };
        String s = fun1.apply(1, "number:");
    }
}

または、カリー化を使用します。

class Demo {
    
    
    public static void main(String[] args) {
    
    
        Function<Integer, Function<String, String>> fun1 = (Integer i) -> (String s) -> {
    
    
            //....
            return s + i;
        };
        String s = fun1.apply(1).apply("number:");
    }
}

(言語に scala や kotlin などの手続き型サポートがある場合、ローカル関数を記述する方がはるかに便利になります)

おすすめ

転載: blog.csdn.net/zssrxt/article/details/131261710