如何初始化匿名类的对象?

How to initialize objects of anonymous classes?

我们不能在匿名中声明构造函数类。但是如果我需要用局部变量的值初始化匿名 类 的对象的状态,我该怎么做?

您可以进行如下操作:

final int localVar = 5;

new Runnable() {
    int innerVar = localVar;  // <--- initialized here

    public void run() {
        System.out.println(innerVar);
    }
}.run();

如果 localVar 发生了变化(不是最终的),您可以使用

解决它
...
final int tmp = localVar;
new Runnable() {
    int innerVar = tmp;
    ...
...

另请注意,如果您需要调用方法或执行其他通常在构造函数中执行的初始化操作,则可以使用实例初始化程序:

final int localVar = 5;

new Runnable() {
    int innerVar;

    // Initialization block executed upon construction of this class
    {
        System.out.println("Initializing an anonymous Runnable");
        innerVar = localVar;
    }

    public void run() {
        System.out.println(innerVar);
    }
}.run();

例如见:Why java Instance initializers?

您认为我们不能使用构造函数来创建匿名 classes 的假设并不完全正确。只有从接口(不能有构造函数)创建匿名 class 时才会出现这种情况。请参阅下面的示例:

public class Main {

    public static class Razzy {
        private final String name;

        public Razzy(final String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }

    public static void main(final String[] args) {
        final Razzy anonymous = new Razzy("Award") {
            @Override
            public String getName() {
                return "Anonymous " + super.getName();
            }
        };
        System.out.println(anonymous.getName());
    }
}

这里 class Razzy 有一个采用字符串的构造函数。在 main 方法中,使用这个单参数构造函数创建了 Razzy 的匿名子class。

输出为:

Anonymous Award

通过这种方式,您可以将局部变量传递给匿名 class 的构造函数。

请注意,匿名 classes 也可以访问其封闭 class:

的字段
public class Main {

    private static String input = "Award";

    public interface Razzy {           
        public String getName();
    }

    public static void main(final String[] args) {
        final Razzy anonymous = new Razzy() {
            @Override
            public String getName() {
                return "Anonymous " + input ;
            }
        };
        System.out.println(anonymous.getName());
    }
}

具有相同的输出。

事实是,您实际上不需要定义构造函数。匿名 class 可以隐式访问封闭方法范围内的任何变量。它们只需要声明为 final(在 Java8 中,不需要 final 关键字,但您仍然不能为它们重新赋值)。

public void enclosingMethod() {
    final int localVariable = 42; // final is necessary

    Runnable r = new Runnable() {
        public void run() {
            // look ma, no constructors!
            System.out.println(localVariable);
        }
    };
    r.run(); // prints 42
}