Java - 匿名クラス(Anonymous class)

匿名クラス(関数)はInnerクラスで、名前のないクラスを指します。クラス定義と同時にオブジェクトを作成できます。 Java の Interface と Class の両方で、匿名関数でオブジェクトを作成できます。

匿名関数を使用する理由は、プログラム内で一度だけオブジェクトにするために使用されるクラスの場合、クラスを定義して生成することが非効率的であるためです。 匿名関数を使用してクラス定義と実装を同時に行うことで、コードの長さを短縮できます。このため、Runnable または Event Listener オブジェクトの生成に主に使用されます。

1. 匿名関数による Interface の実装とオブジェクトの生成

Java の Interface や Abstract クラスは、匿名関数で実装と同時にオブジェクトを生成できます。

以下の方法で匿名クラスのオブジェクトを作成できます。

new InterfaceName() {...}

1.1 例

まず、以下のようにインターフェースを定義しました。

interface MyInterface {
    void doSomething();
}

以下のように、匿名関数を使用してクラス実装と同時にオブジェクトを作成できます。 myClassオブジェクトは名前のないクラスで作られたオブジェクトです。通常、一度だけ生成して再生成されないオブジェクトを作成するときは、匿名関数を使用します。

public class Example {

    interface MyInterface {
        void doSomething();
    }

    public static void main(String[] args) {

        MyInterface myClass = new MyInterface() {
            @Override
            public void doSomething() {
                System.out.println("doSomething");
            }
        };
        myClass.doSomething();
    }
}

Output:

doSomething

2. 匿名関数によるクラスの実装とオブジェクトの生成

匿名関数を使用すると、Parentクラスを継承してクラスを定義し、オブジェクトを作成できます。

Syntaxは次のとおりです。

new ParentClass() {...}

次のようにParentクラスを定義しました。 (abstractで作ってもよく、一般クラスで作ってもいいです。)

public abstract class MyAbstractClass {
    public abstract void doSomething();
}

次のようにクラス実装と同時にオブジェクトを作成できます。

public class Example2 {

    public static abstract class MyAbstractClass {
        public abstract void doSomething();
    }

    public static void main(String[] args) {

        MyAbstractClass myClass = new MyAbstractClass() {
            @Override
            public void doSomething() {
                System.out.println("doSomething");
            }
        };
        myClass.doSomething();
    }
}

3. 匿名関数の定数と変数の参照

次のように、匿名関数内でメンバー変数を参照できます。

MyInterface myClass = new MyInterface() {
    private int bb = 0;

    @Override
    public void doSomething() {
        System.out.println("doSomething: " + bb);
    }
};

static の場合 static final で宣言した定数は参照可能ですが、final ではない static 変数は参照できず、コンパイルエラーが発生します。

MyInterface myClass = new MyInterface() {
    static final int AA = 0;
    // static int aa = 0; // compile error

    @Override
    public void doSomething() {
        System.out.println("doSomething: " + AA);
    }
};

匿名クラスの外側の変数は、finalまたはEffectively finalのみを参照できます。 以下のコードはコンパイルになります。

int aa = 0;
final int bb = 0;
MyInterface myClass = new MyInterface() {
    private int bb = 0;

    @Override
    public void doSomething() {
        System.out.println("doSomething: " + aa);
        System.out.println("doSomething: " + bb);
    }
};

4. 匿名関数とラムダ式の違い

Java - ラムダ式(Lambda)と関数型インタフェース文で匿名関数とラムダ式の違いについて簡単に作成しました。

codechachaCopyright ©2019 codechacha