Saya memiliki program Java yang terlihat seperti ini.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Apa LocalScreen.this
artinya dalam aFuncCall
?
Saya memiliki program Java yang terlihat seperti ini.
public class LocalScreen {
public void onMake() {
aFuncCall(LocalScreen.this, oneString, twoString);
}
}
Apa LocalScreen.this
artinya dalam aFuncCall
?
Jawaban:
LocalScreen.this
mengacu this
pada 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.this
dalam contoh Anda tidak ditentukan. Saya tidak tahu apakah batasan ini benar untuk bytecode. Mungkin tidak.
Itu berarti this
turunan dari LocalScreen
kelas luar .
Menulis this
tanpa 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.this
memungkinkan 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.this
dan this
dalam 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.this
selalu menunjuk ke luar kelas INI yang dirujuk oleh val x, tetapi this
berada 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.this
dalamrun()
harus mengacu pada melampirkana
'sthis
. Apakah saya benar? (Beginilah cara kode yang diperkecil ada di.jar
file aplikasi OSX Kindle Previewer , saya hanya mencoba memahami apa yang saya lihat.)