【问题标题】:Java final anonymous class vs garbage collectorJava最终匿名类与垃圾收集器
【发布时间】:2018-12-05 23:06:23
【问题描述】:

我的问题是当作为参数传递给异步回调时我们应该如何使用匿名类? 例如,如果我有以下代码:

interface MyListener {
    void onSucces(String requestedAction, JSONObject response);
    void onError(String requestedAction, JSONObject response, int statusCode);
};

interface CallbackInterface {
    void onResponse(String requestedAction, JSONObject response, int statusCode);
};

void doAsyncJob(String action, CallbackInterface callbackItf); 


void makeJob(String action, final MyListener listener) {
    doAsyncJob(action, new CallbackInterface {
        void onResponse(String requestedAction, JSONObject response, int statusCode) {
            if (statusCode == 200) {
                listener.onSucces(requestedAction, response);
            } else {
                listener.onError(requestedAction, response, statusCose);
            }
        }
    });
}


for(i = 1; i < 1000; i++) {
    makeJob("Action_" + i, new MyListener{
        void onSucces(String requestedAction, JSONObject response) {
            //process response
        }
        void onError(String requestedAction, JSONObject response, int statusCode) {
            //process error
        });
}

通过每次分配新的侦听器 (MyListener) 在循环中调用“makeJob”,稍后由 “onResponse”,这个监听器有资格成为垃圾收集器吗? 是否需要保留一个对该侦听器的引用,以确保稍后在“onResponse”中使用时不会被丢弃?

【问题讨论】:

    标签: java garbage-collection final anonymous-class


    【解决方案1】:

    当没有其他对象引用对象时,这些对象就有资格进行垃圾回收。

    在您的情况下,MyListener 对象被传递给 makeJob,然后它们被 CallbackInterface 对象引用。请注意,引用不需要是在CallbackInterface 中显式声明的成员变量(实际上,java 运行时会生成一个并复制引用)。

    所以只要CallbackInterface 对象存在,其关联的MyListener 就不会被垃圾回收。这意味着只要 doAsyncJob 在作业运行期间保持对CallbackInterface 的引用,那么MyListener 将始终可用。

    【讨论】:

    • 这也适用于原生对象?我的意思是,如果我有这样的代码:
    • //native function C++ void nativeFunction(new NativeObject()) { ... do async job in native that use the "obj" } this obj什么时候会被垃圾?
    • 所以一些 Java 方法调用了本机方法,正在等待它返回。这意味着该 java 方法仍在 JVM 中,它仍将保持状态 - 包括所有引用,因此 MyListener 仍然是安全的。
    • 对于上述注释“new NativeObject()”中的本机示例,您打算将其用作 Java 的“new”还是 C++ 的“new”运算符?如果是 Java,那么该对象也将像往常一样有资格进行垃圾收集。但是,如果您的意思是“新”是 C++ 的,那么这是一个完全不同的问题,并且该对象不会被 Java 垃圾收集;您必须确保在本机代码中将其删除。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 2011-11-07
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多