2011-12-21 15 views
6

Nếu tôi cóLớp bên trong ẩn danh có luôn ghi lại tham chiếu đến đối tượng "này" (bên ngoài) khi truy cập vào các thành phần nguyên thủy của nó không?

[EDIT: thêm định nghĩa kiểu cho "Nội"]

interface Inner{ 
    public void execute(); 
} 

class Outer{ 
    int outerInt; 
    public void hello(){ 
     Inner inner = new Inner(){ 
      public void execute(){ 
       outerInt=5; 
      } 
     } 

     //later 
     inner.execute(); 
    } 
} 

sẽ gọi đến inner.execute() thiết lập outerInt biến mà đặc biệtOuter đối tượng để 5, bất cứ nơi nào nó là được gọi từ, và miễn là đối tượng Inner tồn tại? Hay nó sẽ thay đổi một bản sao của biến số outerInt và không ảnh hưởng đến đối tượng Outer gốc?

+0

Tôi nghĩ bạn có nghĩa là 'Outer inner = new Outer()'. – toto2

+0

@ toto2 Không, anh ấy đã không làm vậy. Mặc dù 'Inner' không được hiển thị. – Bohemian

+0

@ toto2 Tôi không nghĩ anh ấy đã làm. – corsiKa

Trả lời

3

Để trả lời câu hỏi mới được làm rõ của bạn (từ bình luận cho câu trả lời khác của tôi):

.
Tất cả các lớp bên trong và địa phương sẽ có tham chiếu đến phụ huynh của họ this, ngay cả khi họ không bao giờ sử dụng nó.
Demo.

6

Điều này sẽ chụp và sửa đổi bên ngoài this.

Xem spec

+1

_pun_mục đích_ – SLaks

+0

Đó là, bên trong này không phải là bên ngoài này. –

+0

@ toto2: Không. Sử dụng một trường từ lớp ngoài sẽ chụp _outer_ 'this'. – SLaks

0

Điều này không nhất thiết phải đúng. Bạn không hiển thị là khai báo lớp cho Inner. Nếu Inner có một trường được gọi là outerInt, thì trường đó sẽ được sửa đổi. Nếu không thì OuterInt của Outer sẽ. Nếu bạn run:

public class Outer { 

    int outerInt = 0; 

    public void hello() { 
     Inner inner = new Inner() { 
      @Override 
      public void execute() { 
       outerInt = 5; 
      } 
     }; 

     // later 
     inner.execute(); 
     System.out.println(outerInt); 
    } 

    public static void main(String[] args) { 
     Outer o = new Outer(); 
     o.hello(); 
    } 
} 

class Inner { 
    int outerInt; 

    public void execute() { 

    } 
} 

Bạn sẽ nhận được 0, không phải 5.

Nhưng ý kiến ​​ra outerInt ở Nội, sau đó bạn nhận được 5

+0

Cảm ơn. Tôi đã chỉnh sửa câu hỏi để cho thấy rằng cá thể 'Nội bộ' đã cho không có biến int gọi là 'outerInt'. Liệu đối tượng 'Bên trong' vẫn giữ một tham chiếu đến' điều này' bên ngoài bất kể biến của bên ngoài có được nhắc đến không? – Navigateur

+0

Khi bạn nói outerInt từ bên trong lớp ẩn danh, trước tiên nó sẽ kiểm tra một outerInt trong lớp đó và trong mỗi lớp siêu của nó. Sau đó, nếu không có gì được tìm thấy, nó sẽ kiểm tra một ở bên ngoài và sau đó mỗi lớp siêu của nó và sau đó nếu bên ngoài được chứa trong một lớp, nó sẽ kiểm tra một và vân vân. Nếu không tìm thấy thì bạn sẽ nhận được lỗi biên dịch. Java không bao giờ tạo ra các bản sao ngầm của các đối tượng. – dspyz

+0

Ồ, tôi thấy những gì bạn đang hỏi bây giờ. Hoặc là cho các lớp bên trong vô danh hoặc chỉ các lớp bên trong thường xuyên thì câu trả lời là như nhau. Nếu bạn khai báo một lớp bên trong một lớp khác mà không sử dụng từ khóa tĩnh, thì bạn có thể tưởng tượng rằng cá thể trong đó lớp được khai báo là một phần của định nghĩa lớp. Nếu bạn đặt tên rõ ràng lớp bên trong của bạn (nói lớp MyInner mở rộng bên trong {...), bạn không thể khởi tạo nó với Outer.MyInner mới vì nó không biết trường hợp nào liên kết MyInner với (Sẽ có một lỗi biên dịch cho nó hiệu ứng). Bạn có thể nói o = new Outer(). Và sau đó o.new MyInner(). – dspyz

0

Có. Nhưng nếu bạn có nhu cầu sử dụng thể hiện của lớp ngoài, ví dụ: đi qua một số phương pháp, bạn phải nói Outer.this.