Saya memiliki program Java yang terlihat seperti ini.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Apa LocalScreen.thisartinya dalam aFuncCall?
Saya memiliki program Java yang terlihat seperti ini.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Apa LocalScreen.thisartinya dalam aFuncCall?
Jawaban:
LocalScreen.thismengacu thispada kelas penutup.
Contoh ini harus menjelaskannya:
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();
}
}
Keluaran:
An anonymous Runnable!
A LocalScreen object
Posting ini telah ditulis ulang sebagai artikel di sini .
a.thisdalam contoh Anda tidak ditentukan. Saya tidak tahu apakah batasan ini benar untuk bytecode. Mungkin tidak.
Itu berarti thisturunan dari LocalScreenkelas luar .
Menulis thistanpa qualifier akan mengembalikan instance kelas dalam tempat pemanggilan berada.
Kompiler mengambil kode dan melakukan sesuatu seperti ini dengannya:
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!";
}
}
Seperti yang Anda lihat, ketika kompilator mengambil kelas dalam, ia mengubahnya menjadi kelas luar (ini adalah keputusan desain yang dibuat sejak lama sehingga VM tidak perlu diubah untuk memahami kelas dalam).
Ketika kelas dalam non-statis dibuat, ia membutuhkan referensi ke induk sehingga dapat memanggil metode / variabel akses dari kelas luar.
Bagian dalam kelas dalam ini bukanlah jenis yang tepat, Anda perlu mendapatkan akses ke kelas luar untuk mendapatkan jenis yang tepat untuk memanggil metode onMake.
new LocalScreen$1().run;menjadi new LocalScreen$1(this).run;?
Class.thismemungkinkan akses ke instance dari kelas luar. Lihat contoh berikut.
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();
}
}
Maka Anda akan mendapatkannya.
D: a-b-c-d
C: a-b-c
B: a-b
A: a
Saya tahu apa kebingungan Anda. Saya menemukan masalah sekarang, harus ada adegan khusus untuk membedakannya.
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.##")
}
}
Anda dapat melihat perbedaan antara THIS.thisdan thisdalam operasi INI baru dengan kode hash (. ##)
uji di konsol 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.thisselalu menunjuk ke luar kelas INI yang dirujuk oleh val x, tetapi thisberada di luar operasi baru anonim.
public class a { private class a { public void run() { System.out.println(a.this.toString()); } }Saya mengira itu masalah yang sama; yanga.thisdalamrun()harus mengacu pada melampirkana'sthis. Apakah saya benar? (Beginilah cara kode yang diperkecil ada di.jarfile aplikasi OSX Kindle Previewer , saya hanya mencoba memahami apa yang saya lihat.)