Java:使用局部变量的匿名内部类

标签 java scope anonymous-class

如何在我的匿名内部子类中获取传递给此方法的 userId 的值?

public void doStuff(String userID) {
    doOtherStuff(userID, new SuccessDelegate() {
        @Override
        public void onSuccess() {
            Log.e(TAG, "Called delegate!!!! "+ userID);
        }
    });
}

我收到这个错误:

Cannot refer to a non-final variable userID inside an inner class defined in a different method

我很确定我不能将它指定为最终变量,因为它是一个具有未知值的变量。我听说这种语法确实以某种方式保留了范围,所以我认为一定有一个我还不太了解的语法技巧。

最佳答案

正如这里的其他人所说,局部变量必须是最终的才能被内部类访问。

这(基本上)是为什么...如果您编写以下代码(答案很长,但在底部,您可以获得简短版本:-):

class Main
{
    private static interface Foo
    {
        void bar();
    }

    public static void main(String[] args)
    {
        final int x;
        Foo foo;

        x = 42;
        foo = new Foo()
        {
            public void bar()
            {
                System.out.println(x);
            }
        };

        foo.bar();
    }
}

编译器大致是这样翻译的:

class Main
{
    private static interface Foo
    {
        void bar();
    }

    public static void main(String[] args)
    {
        final int x;
        Foo foo;

        x = 42;

        class $1
            implements Foo
        {
            public void bar()
            {
                System.out.println(x);
            }
        }

        foo = new $1();
        foo.bar();
    }
}

然后是:

class Main
{
    private static interface Foo
    {
        void bar();
    }

    public static void main(String[] args)
    {
        final int x;
        Foo foo;

        x = 42;
        foo = new $1(x);
        foo.bar();
    }

    private static class $1
        implements Foo
    {
        private final int x;

        $1(int val)
        {
           x = val;
        }

        public void bar()
        {
            System.out.println(x);
        }
    }
}

最后是这个:

class Main
{
    public static void main(String[] args) 
    {
        final int x;
        Main$Foo foo;

        x = 42;
        foo = new Main$1(x);
        foo.bar();
    }
}

interface Main$Foo
{
    void bar();
}

class Main$1
    implements Main$Foo
{
    private final int x;

    Main$1(int val)
    {
       x = val;
    }

    public void bar()
    {
        System.out.println(x);
    }
}

重要的是它将构造函数添加到 $1 的位置。想象一下,如果您可以这样做:

class Main
{
    private static interface Foo
    {
        void bar();
    }

    public static void main(String[] args)
    {
        int x;
        Foo foo;

        x = 42;
        foo = new Foo()
        {
            public void bar()
            {
                System.out.println(x);
            }
        };

        x = 1;

        foo.bar();
    }
}

您可能期望 foo.bar() 会打印出 1,但它实际上会打印出 42。通过要求局部变量为 final,就不会出现这种令人困惑的情况。

关于Java:使用局部变量的匿名内部类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3251018/

相关文章:

java - JDBC 中的 Oracle 到 Postgresql 迁移问题

java - 暂停从 Java Web 应用程序发送和接收消息

java - Esper 基于客户的查询非常适合多个客户

C++ 和我的鼠标类全局变量

java - 匿名接口(interface)实现

java - 无法在 Java 中访问匿名类方法

java - 在内存中,activemq 不会跨连接持久存在

c++ - 在 C++ 中声明一个全局作用域变量 const

c# - 在声明之前不能使用局部变量

c++ - 模板 SFINAE 在 conditional_t 内