2011-12-20 27 views
6

tôi đi qua một giao diện như thực hiện nặc danh đến một đối tượng khác nhau như thế này:Đi qua lớp nặc danh

public interface Interface { 
    public int convert (int a); 
} 



public static void main(String[] args) throws IOException, InterruptedException { 

    final int[] array = {1,6,3,5,7,8,4,0,3}; 
    Interface inter = new Interface() {   
     public int convert(int a) { 
     int result = a;     
     for (int i = 0; i < array.length; i++) { 
     a=a+array[i]; 
     }    
     return a; 
     } 
    }; 

    SomeObject ty = new SomeObject(); 
    ty.Test(7, inter); 
} 

public class SomeObject { 

    public void Test(int number, Interface inter) {    
    System.out.println(inter.convert(number)); 
    } 
} 

Câu hỏi của tôi là: làm thế nào để cho nó hoạt động? Làm thế nào để SomeObject biết về mảng không được truyền trực tiếp đến đối tượng (mảng không phải là thành viên của lớp ẩn danh).

Cập nhật
(xin lỗi vì trễ cập nhật)

gì về thành viên vars hoặc các phương pháp phương pháp được sử dụng trong lớp nặc danh? chúng không phải là cuối cùng

Interface inter = new Interface() {    
      public int convert(int a) { 
      int result = a + someMemberVar;     
      for (int i = 0; i < array.length; i++) { 
      a=a+array[i]; 
      }    
      return a; 
      } 
     }; 
+1

Mục đích của dòng 'int result = a;' là gì? –

Trả lời

2

Câu hỏi của tôi hoạt động như thế nào? Làm thế nào SomeObject biết về mảng mà không được chuyển trực tiếp đến đối tượng (mảng không phải là thành viên của lớp ẩn danh).

  • Trả lời: Nó không; trừ khi bạn khai báo array là cuối cùng.
  • Lý do: Nó hoạt động (nếu mảng là cuối cùng) vì vì nó cuối cùng, nó có thể được coi như một hằng số, vì hàm ẩn danh biết không thể thay đổi mảng.

điều gì về vars thành viên hoặc phương pháp phương pháp được sử dụng trong lớp học vô danh ? họ không thức

  • Trả lời: biến Instance và phương pháp (cũng như các biến và phương pháp tĩnh) là trong phạm vi dù sao, khi lớp nặc danh được tạo ra.
+0

có nó là cuối cùng. xin lỗi – omrid

+0

để toàn bộ mảng trong trạng thái hiện tại của nó được truyền cho SomeObject là hằng số? – omrid

+1

Chỉ một tham chiếu đến đối tượng mảng được chuyển đến lớp ẩn danh. Nếu phương thức khai báo đã thay đổi mảng * elements *, lớp ẩn danh sẽ thấy điều đó. –

2

Vì biến phương thức cục bộ được khai báo trực tiếp bên trong khối phương thức, nó chỉ hiển thị trong phương thức, bắt đầu từ câu lệnh tiếp theo sau khai báo. Và theo phương pháp cục bộ, tôi có nghĩa là biến được khai báo bên trong phương thức nhưng bên ngoài bất kỳ khối nào khác (ví dụ: while { /* not here */ }) có thể xuất hiện trong phương thức đó.

Và nếu bạn thấy, lớp ẩn danh của bạn cũng được định nghĩa là lớp địa phương trong cùng một phương thức sau khai báo của array. Đó là lý do tại sao nó được hiển thị cho lớp.

Lý do bạn cần phải thực hiện arrayfinal để có thể sử dụng nó bên trong lớp ẩn danh là biến cục bộ chỉ tồn tại cho đến khi phương thức hoạt động nhưng đối tượng của lớp địa phương có thể sống lâu hơn (ngay cả sau khi phương thức được thực hiện).

+0

Khả năng hiển thị thực sự bị giới hạn bởi các khối. Vì vậy, các biến không phải cục bộ của nó trong một phương thức nhưng nó cũng phải nằm trong cùng một khối. – Stefan

+0

@Stefan: Đúng vậy. –

+0

@Stefan: Cảm ơn. Thay đổi nó từ chỉ địa phương để phương pháp địa phương. –

0

Bạn đang truyền đối tượng Giao diện có quyền truy cập vào mảng vào phương thức SomeObject.

Vì vậy, SomeObject đang sử dụng cùng một đối tượng Giao diện mà bạn đã truyền trên chính.

Vì Giao diện có quyền truy cập vào mảng, bạn có thể sử dụng nó.

Nó không phải là SomeObject đang sử dụng mảng. Nó là đối tượng Interface.

+0

Các lớp ẩn danh có quyền truy cập vào các biến cuối cùng của các phương thức kèm theo của chúng – pringi

0

Java giữ tham chiếu đến tất cả (đối tượng cuối cùng) của lớp bao quanh được sử dụng trong lớp bên trong. Nếu bạn muốn biết làm thế nào thủ thuật này là người giúp việc, thêm dòng sau để thử nghiệm phương pháp:

System.out.println(inter.getClass().getDeclaredConstructors()[0].getParameterTypes()[0].getCanonicalName() 

Và đầu ra của bạn sẽ là "int []"

Vì vậy, trình biên dịch đơn giản tạo ra một constructor cho lớp bên trong và vượt qua các trường cần thiết

+0

tôi đã thêm vào mã cuối cùng :) – omrid

+0

tôi xóa nội dung liên quan cuối cùng –

1

Đây là một phần của quy tắc phạm vi và khả năng hiển thị cho Java. Trong ví dụ hiện tại của bạn, nó được gọi là Closure. Về cơ bản tất cả mọi thứ được xác định trong một khối có thể nhìn thấy bên trong khối đó. Đối với một ví dụ này là mã Java hợp lệ (bất cứ nơi nào trong một phương pháp):

{ 
    final int i = 5; 
    // do somthing with i 
} 
// cant refernce i here 
{ 
    final int i = 6; 
    // do somthing with i 
} 
// cant refernce i here 

Kể từ khi bạn định nghĩa một lớp mới bên trong khối (i wouldnt làm việc nếu bạn chỉ instanciated nó) nó nhìn thấy tất cả mọi thứ đã tuyên bố trong cùng một khối. Giới hạn Java duy nhất đặt trên nó, là bạn không thể thay đổi giá trị sau lần gán đầu tiên, để tránh các vấn đề khi tham chiếu 'thoát' khối của nó (đa luồng, sống lâu hơn khối khai báo, v.v.). Nếu bạn khai báo các tham số của phương thức cuối cùng, bạn có thể sử dụng chúng là tốt, bởi vì chúng được định nghĩa trong cùng một khối.

Vì vậy, nếu bạn đã thay đổi mã của bạn để này

 { 
      final int[] array = {1,6,3,5,7,8,4,0,3}; 
     } 
     Object inter = new Object() 
     {   
      public void test() 
      { 
       System.out.println(array); 
      } 
     }; 

Nó sẽ không hoạt động (thử nó).

Các vấn đề liên quan