4

java - 如何将外部匿名类引用传递给Java内部匿名类中的方法?

我有一种方法可以对服务器进行异步调用 - sendCall(some_args, callback). 回调由匿名类(我们给它命名OuterAnon)表示,并包含一个失败案例的方法。在此方法中,会创建一个消息框,并sendCall()在每次按下 OK 按钮时调用该消息框。所以我需要OuterAnon再次传递给该方法。

这是一个代码来演示我的意思:

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

正如您所注意到的,我在这里为回调提供了一个参考:

final OuterAnon<Boolean> callback = this;

并在这里使用它:

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

但我想避免创建引用并传递回调,例如:

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

有没有办法在Java中做到这一点?

4

2 回答 2

2

我们很难修复,因为您只显示了带有未提供的类的不完整代码,所以我不知道这个示例在语法上是否正确。话虽如此,这样的重构可能会满足您的需求:

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

一般来说,我认为将代码从匿名内部类中抽象出来并放入封闭类上的自己的方法中通常是一个好主意。它现在是可测试的、可重用的和更具可读性的,IMO。

于 2013-05-15T13:59:51.083 回答
1

如果您确实需要以显示代码的方式指定onFailure内部类的内部,并且如果您需要使用该特定引用callback,并且您需要以这种方式编码...

让我们回答这个问题:没有

在我的尝试中,我已经实现了 3 种方法来访问 anon-inner-most 实例中的 anon-inner-least 实例,但我认为没有一种方法可以满足您的期望。

在那种情况下,anon-inner-most 没有对 anon-inner-least 的引用:正如您所说,this现在指向 anon-inner-least。

另外,我尝试搜索java 规范,但找不到问题的确切答案 - 如果有人在那里找到答案,请贡献。

我的尝试:

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("");
    }
}
于 2013-05-15T14:53:46.627 回答