静态方法中的匿名类,持有什么参考?

时间:2015-08-09 21:30:35

标签: java android memory-leaks static-methods anonymous-inner-class

Afaik,在Java中,匿名内部类总是拥有对其外部类的封闭实例的引用。现在当我在静态方法中放入一个匿名类时会发生什么?由于它的外部类没有对象,它是否包含对调用静态方法的类的引用?我在这里有点困惑。考虑下面的Android示例(使用parse.com框架):

public class OnlineQuery {    
    public static void queryUsers(final ListenerInterface listener) {
        ParseQuery<ParseUser> query = User.getQuery();
        query.findInBackground(new FindCallback<ParseUser>() {
            @Override
            public void done(final List<ParseUser> userList, ParseException e) {
            listener.reportBackToCallingActivity();    
            // to which class is as a reference held here?
            }
        });
    }
}

public class MainActivity extends Activity implements OnlineQuery.ListenerInterface {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        OnlineQuery.queryUsers(this)
    }
    ...
}

另外,正如使用示例中所示的关于内存泄漏的错误做法? 谢谢!

2 个答案:

答案 0 :(得分:2)

我做了一个小小的一次性课程(它是Java 9,但我怀疑它有所不同)并使用javap来反汇编它,显然它们没有显式声明包含对外部类的引用的字段,与实例方法中的匿名类不同。

这是源代码:

import java.util.function.Supplier;

/* Temporary program. */
public class Temp
{
    static <T> Supplier<T> refSupplier(T obj)
    {
        return new Supplier<>()
        {
            public T get()
            {
                return null;
            }
        };
    }

    public static void main(String... args) {}
}

这是匿名Supplier的反汇编类文件:

PS C:\Users\Sylvaenn\OneDrive\Documents\Programs\Java\src> javap -c -p Temp`$1
Compiled from "Temp.java"
class Temp$1 implements java.util.function.Supplier<T> {
  Temp$1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public T get();
    Code:
       0: aconst_null
       1: areturn
}

以下是Temp的源代码,静态类替换了匿名类:

import java.util.function.Supplier;

/* Temporary program. */
public class Temp
{
    static class UselessSupplier implements Supplier<Object>
    {
        @Override
        public Object get()
        {
            return null;
        }
    }

    public static void main(String... args) {}
}

这是字节码:

PS C:\Users\Sylvaenn\OneDrive\Documents\Programs\Java\src> javap -c -p Temp$`UselessSupplier
Compiled from "Temp.java"
class Temp$UselessSupplier implements java.util.function.Supplier<java.lang.Object> {
  Temp$UselessSupplier();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public java.lang.Object get();
    Code:
       0: aconst_null
       1: areturn
}

在静态方法中声明的匿名类似乎只是匿名静态类。

答案 1 :(得分:0)

匿名内部类的实例没有对外部类的引用。