简体   繁体   English

如何在Runnable中捕获封闭范围

[英]How to capture enclosing scope in Runnable

I'm trying to do a stream of updates on a HandlerThread using the class below, but I have a couple of questions about how variable capture works in Java. 我正在尝试使用下面的类在HandlerThread进行更新,但是我有几个关于变量捕获在Java中如何工作的问题。

[1] Is ret captured from the enclosing scope by reference? [1]是否通过引用从随附的示波器中捕获了ret

[2] Does this refer to the Runnable , or is it captured from the enclosing scope? [2] this是指Runnable ,还是从封闭范围捕获的?

[bonus] StartStream should post a Runnable to the handler thread, and only return when the Runnable has completed. [奖励] StartStream应该将Runnable到处理程序线程,并且仅在Runnable完成后才返回。 Will the code below work as expected? 下面的代码能按预期工作吗?

public class Stream extends HandlerThread {
    Handler handler = null;

    Stream() {
        super("Stream");
        handler = new Handler(getLooper());
        start();
    }

    private int _startStream() { // Start some repeating update
        return 1;
    }

    public int StartStream() {
        int ret = -1;

        handler.post(new Runnable(){
            @Override public void run() {
                synchronized(this) {
                    ret = _startStream();    // [1]
                    this.notify();           // [2]
                }
            }
        });

        synchronized(this) {
            while(ret == -1) {
                try {
                    this.wait();
                }
                catch (InterruptedException e){}
            }
        }

        return ret;
    }
}

Inner classes have implicit references to outer class. 内部类对外部类有隐式引用。

To use ret in anonymous inner class it should be final. 要在匿名内部类中使用ret ,它应该是最终的。 The reason local variables cannot reference as non-final is because the local class instance can remain in memory after the method returns. 局部变量不能引用为非最终变量的原因是因为方法返回后,本地类实例可以保留在内存中。 It also depends on java version . 它还取决于Java版本 Still it should be "effectively final" or move it to a member variable. 它仍然应该是“有效的最终”或将其移至成员变量。

this refers to the Runnable, you should use Stream.this for enclosing one. this是指Runnable,您应该使用Stream.this来封闭它。

ret is a local variable and thus needs to be effectively final. ret是局部变量,因此需要有效地最终确定。 This means, the compiler complains, if ret is assigned to another value, after it was initialized. 这意味着,在将ret初始化后,如果将ret分配给另一个值,编译器会抱怨。 Thus [1] results in a compiler error. 因此,[1]会导致编译器错误。

This is because the Java language architects want to prevent local variables (variables that are declared in a method) to be changed from somewhere else than the method that declares it. 这是因为Java语言架构师希望防止局部变量(在方法中声明的变量)从声明它的方法之外的其他地方更改。

For more information about variable capture from the enclosing method: 有关从封闭方法捕获变量的更多信息:

this does indeed refer to the Runnable instance. this确实是指Runnable实例。 However, you can use Stream.this to refer to the enclosing Stream instance. 但是,可以使用Stream.this引用封闭的Stream实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 是否可以在封闭范围内使用非最终形式,如可运行(no。) - Is it possible to use a non-final in an enclosing scope like a runnable (no.) 范围内没有任何封闭类型的实例… - no enclosing instance of type… in scope 内部类封闭实例和范围 - Inner Class Enclosing Instance and Scope 范围内不能访问该类型的封闭实例 - No enclosing instance of the type is accessible in scope 如何在不使用“在范围内定义的局部变量x必须是最终的…”的情况下使用数组索引 - How to use array index without “Local variable x defined in an enclosing scope must be final…” 如何解决错误:“我在封闭 scope 中定义的局部变量必须是最终的或有效的最终”? - How can I work around the error: “Local variable i defined in an enclosing scope must be final or effectively final”? Java-范围内没有任何封闭类型的实例… - Java - No enclosing instance of the type … is accessible in scope 作用域bukkit编码中无法访问该类型的封闭实例 - No enclosing instance of the type is accessible in scope bukkit coding Java Streams 的封闭范围必须是最终的 - Enclosing scope must be final with Java Streams 在作用域中无法访问类型为Polylinje的封闭实例 - no enclosing instance of the type Polylinje is accessible in scope
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM