Pass the outer class anon ref to the method in the inner class anon

How to pass an anon ref outer class to a method in an anon inner class in Java?

I have a method that makes an asynchronous call on the server - sendCall(some_args, callback) . The callback is represented by an anonymous class (let its name be OuterAnon ) and contains a method for the case of failure. A message box is created inside this method, and sendCall() is called each time the OK button is clicked. So I need to pass OuterAnon method again.

Here is the code demonstrating what I mean:

 private void sendCall(MyData data, OuterAnon<Boolean> callback){/*...*/} private void myCall(final MyData data) { sendCall(data, new OuterAnon<Boolean>() { public void onFailure(Throwable throwable) { final OuterAnon<Boolean> callback = this; //how to avoid this? MessageBox.show(throwable.getMessage(), new MessageListener() { public void process(MessageBox.OnClick action) { if (action == MessageBox.OnClick.OK) { sendCall(new MyData("resend?"), callback); } } }); } } }); } 

As you noticed, I take the link for the callback here:

 final OuterAnon<Boolean> callback = this; 

and use it here:

 sendCall(new MyData("resend?"), callback); 

But I want to avoid creating a ref and do a callback, for example:

 sendCall(new MyData("resend?"), this); //at the moment we point to MessageListener instead of OuterAnon. 

Is there any way to do this in Java?

+4
source share
2 answers

It’s hard for us to fix, since you were only showing incomplete code with classes that are not supplied, so I don’t know if this example is syntactically correct. At the same time, refactoring like this can satisfy your needs:

  private void myCall(final MyData data) { sendCall(data, new OuterAnon<Boolean>() { public void onFailure(Throwable throwable) { showErrorMessage(throwable); } }); } private void showErrorMessage(Throwable throwable) { MessageBox.show(throwable.getMessage(), new MessageListener() { public void process(MessageBox.OnClick action) { if (action == MessageBox.OnClick.OK) { sendCall(new MyData("resend?")); } } }); } private void sendCall(MyData data) { sendCall(data, this); } 

In general, I find it usually a good idea to abstract the code from the internal anon classes and into your own method on the enclosing class. It can now be tested, reused and read on, IMO.

+2
source

If you really need to specify onFailure inside the inner class, as you showed the code, and if you need to use this specific link for callback , and you need to encode this path ...

Let me answer the question: no.

In my attempts, I have achieved three ways to access the anon-inner-smallest instance inside the anon-inner-most instance, but I think no one meets the expected.

In this case, anon-inner-most has no reference to anon-inner-less: as you said, this now points to anon-inner-less.

In addition, I tried to search the java specification , but could not find the exact answer to the question - if someone finds the answer there, please contribute.

My attempt:

 import java.util.ArrayList; import java.util.LinkedList; public abstract class AnonTest { public static void main(String[] args) { new ArrayList<Object>() { private static final long serialVersionUID = -5986194903357006553L; { // initialize inner anon class add("1"); } // Way 1 private Object thisReference1 = this; // Way 2 private Object getThisReference2() { return this; } @Override public boolean equals(Object obj) { // Way 3 final Object thisReference3 = this; new LinkedList<Object>() { private static final long serialVersionUID = 900418265794508265L; { // initialize inner inner anon class add("2"); } @Override public boolean equals(Object innerObj) { // achieving the instance System.out.println(thisReference1); System.out.println(getThisReference2()); System.out.println(thisReference3); System.out.println(this); System.out.println(); // achieving the class System.out.println(thisReference1.getClass()); System.out.println(getThisReference2().getClass()); System.out.println(thisReference3.getClass()); System.out.println(this.getClass()); System.out.println(this.getClass().getEnclosingClass()); return super.equals(innerObj); } }.equals(""); return super.equals(obj); } }.equals(""); } } 
+1
source

Source: https://habr.com/ru/post/1480944/


All Articles