Khi lớp bên trong được thêm vào Java trong ver sion 1.1 của ngôn ngữ ban đầu được định nghĩa là một biến đổi thành mã tương thích 1.0. Nếu bạn xem xét một ví dụ về sự biến đổi này, tôi nghĩ nó sẽ làm cho nó rõ ràng hơn rất nhiều về cách một lớp bên trong thực sự hoạt động.
xem xét mã từ Ian Roberts' câu trả lời:
public class Foo {
int val;
public Foo(int v) { val = v; }
class Bar {
public void printVal() {
System.out.println(val);
}
}
public Bar createBar() {
return new Bar();
}
}
Khi chuyển đến 1.0 mã tương thích, mà bên trong lớp Bar
sẽ trở thành một cái gì đó như thế này:
class Foo$Bar {
private Foo this$0;
Foo$Bar(Foo outerThis) {
this.this$0 = outerThis;
}
public void printVal() {
System.out.println(this$0.val);
}
}
Tên lớp bên trong là tiền tố với tên lớp bên ngoài để làm cho nó độc đáo. Thành viên riêng tư this$0
bị ẩn được thêm vào giữ bản sao của bên ngoài this
. Và một hàm tạo ẩn được tạo ra để khởi tạo thành viên đó.
Và nếu bạn nhìn vào các phương pháp createBar
, nó sẽ được chuyển đổi thành một cái gì đó như thế này:
public Foo$Bar createBar() {
return new Foo$Bar(this);
}
Vì vậy, chúng ta hãy xem những gì sẽ xảy ra khi bạn thực hiện đoạn mã sau.
Foo f = new Foo(5);
Foo.Bar b = f.createBar();
b.printVal();
tiên chúng ta khởi tạo một thể hiện của Foo
và intialise các val
thành viên để 5 (tức là f.val = 5
).
Tiếp theo chúng ta gọi f.createBar()
, mà instantiates một thể hiện của Foo$Bar
và khởi sự this$0
thành viên với giá trị của this
trôi qua từ createBar
(ví dụ: b.this$0 = f
).
Cuối cùng chúng ta gọi là b.printVal()
mà cố gắng để in b.this$0.val
đó là f.val
đó là 5.
Bây giờ đó là một instantiation thường xuyên của một lớp bên trong. Hãy xem điều gì sẽ xảy ra khi khởi tạo Bar
từ bên ngoài Foo
.
Foo f = new Foo(5);
Foo.Bar b = f.new Bar();
b.printVal();
Áp dụng chuyển đổi 1.0 của chúng tôi một lần nữa, rằng dòng thứ hai sẽ trở thành một cái gì đó như thế này:
Foo$Bar b = new Foo$Bar(f);
này là gần như giống với f.createBar()
gọi. Một lần nữa, chúng tôi đang tạo một thể hiện của Foo$Bar
và khởi tạo thành viên this$0
thành f. Vì vậy, một lần nữa, b.this$0 = f
.
Và một lần nữa khi bạn gọi b.printVal()
, bạn đang in b.thi$0.val
đó là f.val
đó là 5.
Điều quan trọng cần nhớ là các lớp bên trong có thành viên ẩn giữ một bản sao của this
từ lớp bên ngoài. Khi bạn khởi tạo một lớp bên trong từ bên trong lớp bên ngoài, nó được khởi tạo ngầm với giá trị hiện tại là this
. Khi bạn khởi tạo lớp bên trong từ bên ngoài lớp bên ngoài, bạn chỉ định rõ ràng thể hiện của lớp bên ngoài để sử dụng, thông qua tiền tố trên từ khóa new
.
cho bạn tham khảo, [lớp bên trong] (http://docs.oracle.com/javase /tutorial/java/javaOO/nested.html). –
Ngoài ra, tôi đã tin rằng 'new' là một toán tử trong nhiều ngôn ngữ. (Tôi nghĩ rằng bạn cũng có thể quá tải 'mới' trong C + +?) Lớp bên trong của Java là một chút lạ cho tôi, mặc dù. –
Không có câu hỏi ngớ ngẩn nào trên StackOverflow! –