Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Anonymous class in static method, holds reference to what?

Afaik, in Java an anonymous inner class always holds a reference to the enclosing instance of its outer class. Now what happens when I put an anonymous class inside a static method? As there is no object of its outer class, does it hold a reference to the class that calls the static method? I am a bit confused here. Consider the Android example below (using the parse.com framework):

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)
    }
    ...
}

Also, is using a listener as shown in the example bad practice regarding memory leaks? Thanks!

like image 908
fnberta Avatar asked Oct 31 '22 21:10

fnberta


1 Answers

I made a little throwaway class (it's Java 9, but I doubt that makes a difference) and used javap to disassemble it, and apparently they do not explicitly declare a field containing a reference to the outer class, unlike anonymous classes in instance methods.

Here's the source code:

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) {}
}

And here's the disassembled class file for the anonymous 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
}

Here's the source code for Temp, with a static class replacing the anonymous class:

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) {}
}

And here's its bytecode:

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
}

It appears that anonymous classes declared in static methods are simply anonymous static classes.

like image 100
Isaac Saffold Avatar answered Nov 11 '22 14:11

Isaac Saffold