【问题标题】:Pass outer anon class ref to a method in an inner anon class将外部匿名类 ref 传递给内部匿名类中的方法
【发布时间】:2013-05-15 12:28:17
【问题描述】:

如何将外部匿名类 ref 传递给 Java 内部匿名类中的方法?

我有一个异步调用服务器的方法 - sendCall(some_args, callback)。回调由匿名类(我们将其命名为OuterAnon)表示,并包含一个失败案例的方法。在此方法中,会创建一个消息框,并且每次按下 OK 按钮时都会调用 sendCall()。所以我需要再次将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);
                            }
                        }
                    });
                }
            }
        });
    }

正如你所注意到的,我在这里为回调取一个 ref:

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 中实现吗?

【问题讨论】:

  • 因为这里的外部类也是匿名的所以我认为没有办法做到这一点,如果外部类有一些名字那么它可以用 .this
  • @Krushna,尝试使用 OuterAnon.this 访问它会导致错误:“OuterAnon 不是封闭类”

标签: java oop scope anonymous-class anonymous-inner-class


【解决方案1】:

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

  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。

【讨论】:

    【解决方案2】:

    如果您真的需要以显示代码的方式在内部类中指定 onFailure,并且如果您需要使用 @987654323 的特定引用@,而您需要以这种方式编码...

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

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

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

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

    我的尝试:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      • 2011-07-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多