2009-02-05 42 views
7

Nếu tôi viết lớp sau:Việc sử dụng "này" trong Java

public class Example { 

     int j; 
     int k; 

     public Example(int j, int k) { 
      j = j; 
      k = k; 
     } 

     public static void main(String[] args) { 
      Example exm = new Example(1,2); 
      System.out.println(exm.j); 
      System.out.println(exm.k); 
     } 

} 

Chương trình biên dịch, nhưng khi tôi chạy chương trình, phương pháp chính sẽ in ra hai 0s. Tôi biết rằng để nói rằng tôi muốn khởi tạo các biến Ví dụ trong constructor tôi phải viết:

this.j = j; 
this.k = k; 

Nhưng nếu tôi không viết nó, sau đó biến được đánh giá (hoặc xem xét) trong constructor (ở bên trái và trên mặt viết của các biểu thức)? Là đối số hoặc biến mẫu? Liệu nó có làm cho một sự khác biệt?

Có trường hợp nào khác khi bắt buộc sử dụng this không?

+4

Loại lỗi này là lý do chính đáng để làm cho thông số của bạn cuối cùng. –

+0

Bạn cũng có thể xem: http://stackoverflow.com/questions/132777/do-you-prefix-your-instance-variable-with-this-in-java – VonC

+1

Ở một trong những nơi tôi đã làm việc, họ không bao giờ cho phép các tham số được thay đổi nhưng cũng không bao giờ cho phép các tham số được đánh dấu "cuối cùng" là tốt. Và tôi giống như kiểu đó. Đó là, err, phong cách :) – Srikanth

Trả lời

6

Nếu bạn không viết điều này, sau đó bạn chỉ định đối số cho chính nó; các biến đối số đổ bóng các biến mẫu.

30

Nếu bạn không viết "this.variable" trong hàm tạo của mình và nếu bạn có biến cục bộ (bao gồm tham số hàm) có cùng tên với biến trường của bạn trong hàm tạo thì biến cục bộ sẽ là xem xét; biến cục bộ đổ bóng trường (biến lớp).

Một nơi "này" là cách duy nhất để đi:

class OuterClass { 
    int field; 

    class InnerClass { 
    int field; 

    void modifyOuterClassField() 
    { 
     this.field = 10; // Modifies the field variable of "InnerClass" 
     OuterClass.this.field = 20; // Modifies the field variable of "OuterClass", 
            // and this weird syntax is the only way. 
    } 
    } 
} 
+1

Đẹp bắt: kinh dị của các lớp bên trong :) –

+0

@ Robert: Cảm ơn! Có, tránh càng nhiều càng tốt :) – Srikanth

+1

Bạn chắc chắn xứng đáng là một upvote, chỉ cần đến xung quanh tìm kiếm "này" trên google và tìm thấy ví dụ đơn giản nhất của bạn. tuyệt vời :) – 0decimal0

5

này rất hữu ích khi bạn muốn trả lại đối tượng tự

return this; 

này rất hữu ích bởi vì nếu một lớp học có ví dụ Method1() và Method2(), cả hai đều trả về điều này, bạn được phép viết các cuộc gọi như

object.Method1().Method2() 

Bên trong một phương thức có thể hữu ích khi truyền đối tượng đến một hàm khác, trong khi gọi.

3

Trong mã trình xây dựng, bạn chỉ định các biến cho chính chúng. 'j' là j được chỉ định trong đối số cho hàm tạo. Ngay cả khi đó là biến lớp j được định nghĩa ở trên, thì bạn vẫn đang nói "j = j" ... tức là j sẽ không đánh giá khác nhau ở bên trái và bên phải.

public Example(int j, int k) { 
     this.j = j; 
     this.k = k; 
    } 
10

Nếu bạn nói chỉ j trong hàm tạo của bạn thì trình biên dịch sẽ nghĩ bạn là đối số trong cả hai trường hợp. Vì vậy,

j = j; 

chỉ đơn giản là gán giá trị của đối số j cho lập luận j (đó là một tuyên bố khá vô nghĩa, nhưng dù sao hợp lệ).

Vì vậy, để phân biệt điều này, bạn có thể tiền tố this. để làm rõ rằng bạn có nghĩa là biến thành viên có cùng tên.

Việc sử dụng khác của this là khi bạn cần phải vượt qua một tham chiếu đến đối tượng hiện hành đối với một số phương pháp, ví dụ như thế này:

someObject.addEventListener(this); 

Trong ví dụ này, bạn cần phải tham khảo các đối tượng hiện tại như một toàn thể (thay vì chỉ là thành viên của đối tượng).

2

Bạn chỉ định thông số cho chính nó trong ví dụ của bạn.

Nói chung hơn: Nếu bạn không thêm một phạm vi vào biến của mình, phạm vi hiện tại được giả định - đó là hàm trong trường hợp của bạn. 'this.j' yêu cầu jre sử dụng biến j trong phạm vi đối tượng - biến thành viên của đối tượng.

1

Giống như Robert Grant đã nói, 'đây' là cách bạn làm rõ rằng bạn đang đề cập đến biến thành viên thay vì biến cục bộ.

3

Những gì bạn đang gặp phải được gọi là variable shadowing. Hãy xem tổng quan này cho different kinds of variables in Java.

Nói chung: Trình biên dịch Java sử dụng biến gần nhất mà nó có thể tìm thấy cho một bài tập. Trong một phương thức, đầu tiên nó sẽ cố gắng tìm một biến cục bộ và sau đó mở rộng trọng tâm của tìm kiếm của nó thành các biến lớp và các cá thể.

Một thói quen cá nhân tôi tìm thấy tốt (những người khác không thích nó) là tiền tố biến thành viên với m_ và sử dụng chữ hoa cho CONSTANT_VARIABLES không thay đổi giá trị của chúng. Mã nơi bóng đổ biến được sử dụng cho mục đích là rất (!) Khó gỡ lỗi và làm việc với.

+0

Các hằng số không bao giờ thay đổi phải được khai báo cuối cùng, thì không thể ghi đè các giá trị của chúng một cách vô tình. –

5

Một cách tiếp cận hữu ích (mặc dù hiếm khi được sử dụng) là để khai báo các thông số phương pháp cuối cùng:

Khối sau đây sẽ không biên dịch, do đó cảnh báo cho bạn để các lỗi ngay lập tức:

public Example(final int j, final int k) { 
     j = j; 
     k = k; 
    } 
+0

Tôi không thích sử dụng cuối cùng cho các biến địa phương trừ khi nó là bắt buộc (nhưng đối với các biến mẫu, tôi sử dụng chúng luôn luôn khi có thể). Tôi thấy nó quá lộn xộn. Thay vào đó, tôi sử dụng mã của IDE làm nổi bật. Xem nhận xét của tôi tại đây http://blog.objectmentor.com/articles/2008/10/28/data-rattle#comment-2155 –

1

Để trả lời follow-up question about this with method của bạn, các inner class mentioned by Srikanth is still a valid example of using this: (với phương pháp thời gian này)

public class OuterClass 
{ 
    void f() {System.out.println("Outer f()");}; 
    class InnerClass { 
     void f() { 
      System.out.println("Inner f()"); 
      OuterClass.this.f(); 
     } 
    } 
} 

Bạn có tình hình tương tự với anonymous class:

Bạn có thể tham khảo phương pháp của lớp bên ngoài bằng cách:

  • MyOuterClass.this.yOuterInstanceMethod(),
  • MyOuterClass.myOuterInstanceMethod(),
  • hoặc đơn giản là myOuterInstanceMethod()nếu không có sự nhập nhằng.
0

Điều này không trả lời câu hỏi của bạn, nhưng nếu bạn sử dụng Eclipse, bạn có thể thấy cài đặt "Chuyển nhượng không có hiệu lực" có ích. Tôi chắc chắn điều này sẽ được trong IDE khác quá.

0

Để tránh điều này, hãy sử dụng một IDE (như Eclipse) và nó sẽ tạo ra cảnh báo trong trường hợp này.

Ngoài ra, hãy đặt trường của bạn cuối cùng trừ khi chúng hoàn toàn không thể. Có một số lý do (ngoài việc này) để làm điều đó.

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