【问题标题】:who is 'this' inside an anonymous class implementation?谁是匿名类实现中的“this”?
【发布时间】:2021-04-15 00:28:48
【问题描述】:

我无法弄清楚 this 在匿名类方法中引用的对象是什么。 两个例子:

  1. 如果我为 onClick 实现匿名实现,例如:
View.setOnClickListener(new View.onClick() {
    public void onClick(View v) {
        ...
        this.   //to which object this refers?
   }
}

2.假设我有以下界面:

interface  WebResponseHandler {
    public void onWebResponseFinished(String jsonString)
}

在某个类中,我定义了一个实现上述接口的变量:

private onInitWebResponseHandler = new VolleyHandler.WebResponseHandler() {
    public void onWebResponseFinished(String jsonString) {
            .....
            this    // to which object this refers to?
    }
}

惊讶在第二个例子中 this 指的是类 private onInitWebResponseHandleronInitWebResponseHandler 的一部分而不是直接引用

【问题讨论】:

  • 我敢说,是“这个”。
  • 在我看来这不像 Java 语法。或者是什么版本?
  • @Bentaye,现在全部使用 Java
  • 注意:异步修改实例变量是不好的做法。您应该使用回调结果调用其他方法
  • @OneCricketeer,对不起,我没听懂你的意思

标签: java android anonymous-class


【解决方案1】:

让我们测试一下:

public class Test {

    private String s = "Test Class";

    public void myMethod() {

        System.out.println("this.s: " + this.s);

        new Callable<String>() {
            private String s = "Callable Class";

            @Override
            public String call() {
                System.out.println("this.s: " + this.s);
                System.out.println("Test.this.s: " + Test.this.s);
                return null;
            }
        }.call();
    }


    public static void main(String[] args) {
        new Test().myMethod();
    }
}

打印出来

this.s: Test Class
this.s: Callable Class
Test.this.s: Test Class

所以匿名类中的this就是匿名类

编辑:添加了Test.this.s,正如Angel Koh所指出的那样

【讨论】:

  • 我理解你的例子,但我仍然对我的情况感到惊讶。您能否参考我帖子中的两个示例?
  • @Bentaye,如果你想在可调用对象中访问Test的“s”参数,你可以使用Test.this.s
  • @AngelKoh 很好,我什至不知道这个,我把它添加到答案中
  • @Eitanos30 在您的第一个示例中,这应该是您的第二个示例中的匿名 OnClickListener,它应该是 onInitWebResponseHandler,因为它是使用 this 的类
  • @Bentaye,谢谢,所以也许在 Kotlin 中,因为 lambda 表达式不同。我会批准你的回答并作为 Kotlin 问题提出一个新问题
【解决方案2】:

关于你的第二个问题。 “this”指的是最里面的对象。

结果会是

HelloWorld@6d06d69c helloWorld
1: HelloWorld$VolleyHandler@7852e922 volley
2: HelloWorld$1@4e25154f anon
3: HelloWorld$2@70dea4e anon2

以下代码

public class HelloWorld{
    

     String s="helloWorld";
     public static void main(String []args){
         
         HelloWorld hw = new HelloWorld();
         hw.run();
         hw.onInitWebResponseHandler1.onWebResponseFinished("1");
         hw.onInitWebResponseHandler2.onWebResponseFinished("2");
          
         hw.onInitWebResponseHandler3.onWebResponseFinished("3");
          
        
     }
    
     public void run(){
         System.out.println(this.toString()+" "+s);
         
         
     }
     
     interface WebResposeHandler {
         public void onWebResponseFinished(String jsonString);
     }   
     
      

    class VolleyHandler implements  WebResposeHandler {
         String s="volley";
         public void onWebResponseFinished(String jsonString){
             System.out.println("1: "+this.toString() +" "+ this.s);
         }
     }  
     
     WebResposeHandler onInitWebResponseHandler1 = new VolleyHandler();
     WebResposeHandler onInitWebResponseHandler2 = new WebResposeHandler(){
         String s="anon";
         public void onWebResponseFinished(String jsonString){
             System.out.println("2: "+this.toString() +" "+ this.s);
         }
     }; 
     WebResposeHandler onInitWebResponseHandler3= new WebResposeHandler(){
         String s="anon2";
         public void onWebResponseFinished(String jsonString){
             System.out.println("3: "+this.toString() +" "+ this.s);
         }
     }; 

}

【讨论】:

  • Kog,输出的第三行不清楚:(只加了'1'?
  • 第三个输出来自接口的匿名类。你会注意到它会打印“HelloWorld$1@xxxx”> 因为匿名类没有“名称”,java 会逐项列出它 1,2,3... 等(基本上是 HelloWorld 类中的第一个匿名类)。
  • @Eitanos30 我已经编辑了代码,有2个匿名类,你看看效果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
  • 2012-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多