简体   繁体   English

Java:Class.this

[英]Java: Class.this

I have a Java program that looks like this.我有一个看起来像这样的 Java 程序。

public class LocalScreen {

   public void onMake() {
       aFuncCall(LocalScreen.this, oneString, twoString);
   }
}

What does LocalScreen.this means in aFuncCall ? LocalScreen.thisaFuncCall是什么意思?

LocalScreen.this refers to this of the enclosing class. LocalScreen.this指的是封闭类的this

This example should explain it:这个例子应该解释一下:

public class LocalScreen {
    
    public void method() {
        
        new Runnable() {
            public void run() {
                // Prints "An anonymous Runnable"
                System.out.println(this.toString());
                
                // Prints "A LocalScreen object"
                System.out.println(LocalScreen.this.toString());
                
                // Won't compile! 'this' is a Runnable!
                onMake(this);
                
                // Compiles! Refers to enclosing object
                onMake(LocalScreen.this);
            }
            
            public String toString() {
                return "An anonymous Runnable!";
            }
        }.run();
    }
    
    public String toString() { return "A LocalScreen object";  }
    
    public void onMake(LocalScreen ls) { /* ... */ }
    
    public static void main(String[] args) {
        new LocalScreen().method();
    }
}

Output:输出:

An anonymous Runnable!
A LocalScreen object

This post has been rewritten as an article here .这篇文章在这里被改写为一篇文章。

It means the this instance of the outer LocalScreen class.这意味着外部LocalScreen类的this实例。

Writing this without a qualifier will return the instance of the inner class that the call is inside of. this没有限定符的情况下编写this将返回调用所在的内部类的实例。

The compiler takes the code and does something like this with it:编译器获取代码并使用它执行以下操作:

public class LocalScreen 
{
    public void method() 
    {
        new LocalScreen$1(this).run;
    }

    public String toString() 
    {
        return "A LocalScreen object"; 
    }

    public void onMake(LocalScreen ls) { /* ... */ }

    public static void main(String[] args) 
    {
        new LocalScreen().method();
    }
}

class LocalScreen$1
     extends Runnable
{
    final LocalScreen $this;

    LocalScreen$1(LocalScreen $this)
    {
        this.$this = $this;
    }

    public void run() 
    {
        // Prints "An anonymous Runnable"
        System.out.println(this.toString());

        // Prints "A LocalScreen object"
        System.out.println($this.toString());

        // Won't compile! 'this' is a Runnable!
        //onMake(this);

        // Compiles! Refers to enclosing object
        $this.onMake($this);
    }

    public String toString() 
    {
        return "An anonymous Runnable!";
    }
}

As you can see, when the compiler takes an inner class it converts it to an outer class (this was a design decision made a LONG time ago so that VMs did not need to be changed to understand inner classes).如您所见,当编译器采用内部类时,它会将其转换为外部类(这是很久以前的设计决策,因此无需更改 VM 即可理解内部类)。

When a non-static inner class is made it needs a reference to the parent so that it can call methods/access variables of the outer class.当创建非静态内部类时,它需要对父类的引用,以便它可以调用外部类的方法/访问变量。

The this inside of what was the inner class is not the proper type, you need to gain access to the outer class to get the right type for calling the onMake method.内部类中的 this 不是正确的类型,您需要访问外部类以获得调用 onMake 方法的正确类型。

Class.this allows access to instance of the outer class. Class.this允许访问外部类的实例。 See the following example.请参阅以下示例。

public class A
{
  final String name;
  final B      b;
  A(String name) {
    this.name = name;
    this.b = new B(name + "-b");
  }

  class B
  {
    final String name;
    final C      c;
    B(String name) {
      this.name = name;
      this.c = new C(name + "-c");
    }

    class C
    {
      final String name;
      final D      d;
      C(String name) {
        this.name = name;
        this.d = new D(name + "-d");
      }

      class D
      {
        final String name;
        D(String name) {
          this.name = name;
        }

        void printMe()
        {
          System.out.println("D: " + D.this.name); // `this` of class D
          System.out.println("C: " + C.this.name); // `this` of class C
          System.out.println("B: " + B.this.name); // `this` of class B
          System.out.println("A: " + A.this.name); // `this` of class A
        }
      }
    }
  }
  static public void main(String ... args)
  {
    final A a = new A("a");
    a.b.c.d.printMe();
  }
}

Then you will get.然后你会得到。

D: a-b-c-d
C: a-b-c
B: a-b
A: a

For those who are beginners in java can understand example by @aioobe better. 对于那些是Java初学者的人,可以更好地通过@aioobe理解示例。

public class LocalScreen {

    public void method() {
        LocalScreen rootThis = this;
        new Runnable() {
            public void run() {
                // Prints "An anonymous Runnable"
                System.out.println(this.toString());

                // Prints "A LocalScreen object"
                System.out.println(rootThis.toString());

                // Won't compile! 'this' is a Runnable!
                //onMake(this);

                // Compiles! Refers to enclosing object
                onMake(rootThis);
            }

            public String toString() {
                return "An anonymous Runnable!";
            }
        }.run();
    }

    public String toString() { return "A LocalScreen object";  }

    public void onMake(LocalScreen ls) { /* ... */ }

    public static void main(String[] args) {
        new LocalScreen().method();
    }
}

I know what is your confusion.I am encounter the problem just now, it should have special scene to distinguish them.我知道你的困惑是什么。我刚刚遇到这个问题,应该有特殊的场景来区分它们。

class THIS {
  def andthen = {
    new THIS {
      println(THIS.this.## + ":inner-THIS.this.##")
      println(this.## + ":inner-this.##")
      new THIS {
        println(THIS.this.## + ":inner-inner-THIS.this.##")
        println(this.## + ":inner-this.##")
      }
    }
  }
  def getInfo = {
    println(THIS.this.## + ":THIS.this.##")
    println(this.## + ":this.##")
  }
}

You can see the diff between THIS.this and this in new THIS operation by hashcode( .## )您可以通过 hashcode( .## ) 在新的 THIS 操作中看到THIS.thisthis之间的差异

test in scala console :在 Scala 控制台中测试:

scala> val x = new THIS
x: THIS = THIS@5ab9b447

scala> val y = x.andthen
1522119751:inner-THIS.this.##
404586280:inner-this.##
1522119751:inner-inner-THIS.this.##
2027227708:inner-this.##
y: THIS = THIS$$anon$1@181d7f28

scala> x.getInfo
1522119751:THIS.this.##
1522119751:this.##

THIS.this always point to outer THIS class which is refer by val x,but this is beyond to anonymous new operation. THIS.this总是指向外这个类是由VAL指X,但是this超出了匿名新的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM