簡體   English   中英

Java:Class.this

[英]Java: Class.this

我有一個看起來像這樣的 Java 程序。

public class LocalScreen {

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

LocalScreen.thisaFuncCall是什么意思?

LocalScreen.this指的是封閉類的this

這個例子應該解釋一下:

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

輸出:

An anonymous Runnable!
A LocalScreen object

這篇文章在這里被改寫為一篇文章。

這意味着外部LocalScreen類的this實例。

this沒有限定符的情況下編寫this將返回調用所在的內部類的實例。

編譯器獲取代碼並使用它執行以下操作:

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!";
    }
}

如您所見,當編譯器采用內部類時,它會將其轉換為外部類(這是很久以前的設計決策,因此無需更改 VM 即可理解內部類)。

當創建非靜態內部類時,它需要對父類的引用,以便它可以調用外部類的方法/訪問變量。

內部類中的 this 不是正確的類型,您需要訪問外部類以獲得調用 onMake 方法的正確類型。

Class.this允許訪問外部類的實例。 請參閱以下示例。

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

然后你會得到。

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

對於那些是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();
    }
}

我知道你的困惑是什么。我剛剛遇到這個問題,應該有特殊的場景來區分它們。

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.##")
  }
}

您可以通過 hashcode( .## ) 在新的 THIS 操作中看到THIS.thisthis之間的差異

在 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總是指向外這個類是由VAL指X,但是this超出了匿名新的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM