2010-03-11 33 views
60

Thực tiễn tốt nhất để sử dụng từ khóa this trong Java là gì? Ví dụ, tôi có lớp sau đây:Java - khi nào nên sử dụng từ khoá 'này'

class Foo { 
    Bar bar; 

    public Foo(Bar bar) { 
     this.bar = bar; 
    } 
} 

Đó là tốt và tất cả, nhưng Java là đủ thông minh để biết những gì đang xảy ra nếu tôi thay đổi tuyên bố trong constructor để

bar = bar; 

Vậy tại sao sử dụng từ khóa this? (Tôi nhận ra trong một số tình huống, nó hoàn toàn cần thiết để sử dụng nó, tôi chỉ yêu cầu cho các tình huống như thế này). Trên thực tế, tôi có xu hướng sử dụng từ khóa hoàn toàn cho sake dễ đọc nhưng thực tế phổ biến là gì? Sử dụng nó trên tất cả các cửa hàng làm cho mã của tôi trông hơi lộn xộn, ví dụ:

boolean baz; 
int someIndex = 5; 
this.baz = this.bar.getSomeNumber() == this.someBarArray[this.someIndex].getSomeNumber(); 

Rõ ràng là một chút mã nhưng nó minh họa ví dụ của tôi. Nó chỉ là sở thích cá nhân trong những trường hợp này?

+3

Cùng một câu hỏi đã được đăng 2 ngày trước: http://stackoverflow.com/questions/2411270/when-should-i-use-this-in-a-class Có bằng cách này nhiều giá trị nhân bản: http://www.google.com/search?q=java+when+use+this+keyword+site%3Astackoverflow.com – BalusC

+0

Tệ của tôi, tôi đã tìm kiếm nhanh (rõ ràng) bằng cách sử dụng tìm kiếm SO nhưng không tìm thấy bất cứ điều gì ... – jackbot

+0

Như những người khác đã chỉ ra, bạn đang làm nhiệm vụ để tự (tham số) ở trên. Nhưng quy tắc của tôi là sử dụng 'this' khi nó làm cho chương trình dễ đọc hơn *. Nếu bạn sử dụng một số loại quy ước đặt tên cho các biến thành viên (ví dụ: '_bar' hoặc' mBar'), thì việc viết 'this._bar' chỉ là thêm tiếng ồn, IMHO. –

Trả lời

69

nhưng Java là đủ thông minh để biết những gì đang xảy ra nếu tôi thay đổi tuyên bố trong constructor để

bar = bar; 

FALSE! Nó biên dịch nhưng nó không làm những gì bạn nghĩ nó!

Khi sử dụng, rất nhiều tùy chọn là sở thích cá nhân. Tôi thích sử dụng this trong các phương pháp công khai của tôi, ngay cả khi nó không cần thiết, bởi vì đó là nơi giao tiếp xảy ra và nó rất tốt để khẳng định những gì của tôi và những gì không.

Là tài liệu tham khảo, bạn có thể kiểm tra của Oracle Java Tutorials hiểu về this.subject ;-)

http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

+11

Thats lý do tại sao tôi muốn đánh dấu tất cả các biến tham số là cuối cùng. – crowne

+0

vâng nó chỉ gán lại thanh biến trong contructor cho chính nó. Điều này là do thanh đã được xác định trong phạm vi và nó vượt qua một từ thanh Bar. –

3

Đó là sở thích cá nhân - chọn kiểu và dán vào nó. Cá nhân tôi sử dụng this nhưng những người khác nghĩ rằng đó là dư thừa.

3

Tùy thuộc vào quy ước, bạn có thể sử dụng nó cho dễ đọc. Nó nhấn mạnh thực tế rằng nó là một biến đối tượng.

Tôi cũng muốn có đối số setter có cùng tên với biến (trông đẹp hơn trong chữ ký phương thức). Bạn cần this trong trường hợp này.

11

Trên thực tế

baz = baz 

sẽ nâng cao cảnh báo này

Việc chuyển nhượng để baz biến không có hiệu lực thi hành

Vì vậy, những gì bạn nghĩ là sai, phạm vi địa phương ghi đè lên lớp thuộc tính để bạn PHẢI sử dụng this keywo rd explictly để gán biến cho thuộc tính class.

Nếu không, biến được tính vào nhiệm vụ chỉ là biến được chuyển thành tham số và lớp được bỏ qua.Đó là lý do tại sao this là hữu ích, nó không phải là một thực tế của dễ đọc, đó là một thực tế của một cách rõ ràng quyết định mà baz là bạn nói về.

tôi sẽ nói

sử dụng this bất cứ nơi nào không sử dụng nó sẽ gây ra sự mơ hồ (hoặc cảnh báo trình biên dịch, mà quan trọng hơn), nếu không chỉ để lại nó. Vì mục đích của nó là chính xác để giải quyết sự mơ hồ khi các giả định mặc định (kiểm tra địa phương đầu tiên, sau đó kiểm tra các thuộc tính lớp) là không đủ.

12

Bạn nên sử dụng nó khi bạn có thông số có cùng tên với trường nếu không bạn sẽ gặp sự cố. Nó sẽ biên dịch, nhưng không nhất thiết phải làm những gì bạn muốn.

Đối với mọi nơi khác, không sử dụng trừ khi cần thiết vì mục đích dễ đọc. Nếu bạn sử dụng nó ở khắp mọi nơi, 20% mã của bạn sẽ bao gồm từ 'this'!

+0

Mặc dù có thể cho rằng từ khóa 'this' rõ ràng ở khắp mọi nơi có thể hữu ích. Các ngôn ngữ như Python và Rust yêu cầu nó trong thực tế ('self'), và tôi chưa bao giờ thấy nhân chứng này là một tiêu cực. – phoenix

+0

Câu trả lời sáng chói, ngắn gọn, súc tích, đến điểm –

6
public Foo(Bar bar) { 
    this.bar = bar; 
} 

là không giống như

public Foo(Bar bar) { 
    bar = bar; 
} 

Trong trường hợp thứ hai thanh trong phạm vi là tham số, vì vậy bạn gán nó cho chính nó. this.bar vẫn là null.

1

Tùy chọn cá nhân, nhưng tôi sử dụng nó để giải quyết sự mơ hồ chỉ, và tôi cho rằng trong trường hợp rất hiếm hoi để làm cho nó rõ ràng rằng biến được gán là một trường. Có một số dự án mà mọi người sử dụng "this.field" trên mọi tham chiếu trường duy nhất. Tôi thấy thực tế này làm mất tập trung một cách trực quan đến mức đáng ghét, nhưng bạn nên chuẩn bị để xem mã như vậy một lần trong một thời gian. Tôi bí mật nghĩ rằng có một nơi đặc biệt trong địa ngục cho những người viết 500 dòng có 275 'từ khóa này' trong họ, nhưng phong cách này được tìm thấy trong một số dự án mã nguồn mở, do đó, tôi đoán.

+0

+1 Nếu tìm thấy bằng cách này. * Ở mọi nơi rất khó chịu. Nếu bạn đang sử dụng IDE hiện đại và thiết kế các lớp học đúng cách, bạn sẽ không bao giờ gặp phải tình huống mà bạn phải tìm ra tham chiếu đến biến là gì (thuộc tính, biến cục bộ, v.v.) – helpermethod

2

Tôi luôn cố gắng sử dụng từ khóa this trên các đối tượng lớp địa phương.

Tôi sử dụng nó để trực quan nhắc nhở tôi nếu một đối tượng là đối tượng tĩnh hoặc đối tượng lớp.

Nó giúp tôi và trình biên dịch phân biệt giữa phương thức arg và đối tượng lớp địa phương.

public void setValue(int value){ 
    this.value = value; 
} 

Nó giúp tôi trực quan nhắc nhở tôi nếu có một đối tượng địa phương trong một lớp bên trong/lồng nhau/ẩn danh để phân biệt nó với việc đóng gói các đối tượng lớp. Bởi vì không this nếu có tiền tố, ước của tôi sẽ nhắc nhở tôi rằng đó là một đối tượng của lớp Encapsulating

public class Hello{ 
    public int value = 0; 
    public boolean modal = false; 

    public class Hellee{ 
    public int value = 1; 
    public getValue(){ 
     if (modal) 
     return 0; 
     return this.value; 
    } 
    } 
} 
10

this từ khóa liên quan đến đối tượng của lớp mà trên đó một số phương pháp được gọi.
Ví dụ:

public class Xyz { 
    public Xyz(Abc ob) 
    { 
     ob.show(); 
    } 
} 

public class Abc { 
    int a = 10; 

    public Abc() 
    { 
     new Xyz(this); 
    } 

    public void show() 
    { 
     System.out.println("Value of a " + a); 
    } 

    public static void main(String s[]) 
    { 
     new Abc(); 
    } 
} 

đây trong Abc() chúng tôi đang kêu gọi Xyz() mà cần Object của Abc Lớp .. Vì vậy, chúng ta có thể vượt qua this thay vì mới Abc(), bởi vì nếu chúng ta vượt qua mới Abc() đây nó sẽ gọi riêng của mình một lần nữa và lần nữa.

Ngoài ra, chúng tôi sử dụng điều này để phân biệt các biến của lớp và biến cục bộ của phương pháp. ví dụ:

class Abc { 
    int a; 

    void setValue(int a) 
    { 
     this.a = a; 
    } 
} 

Đây là một biến thể của lớp Abc. Do đó có tác dụng tương tự như bạn sử dụng mới Abc().a;.

Vì vậy, bạn có thể nói this đề cập đến đối tượng của lớp hiện tại.

0

Sử dụng nó để nhân bản đối tượng (bằng cách chuyển tham chiếu của chính nó thông qua một hàm tạo bản sao).

Hữu ích cho đối tượng kế thừa Cloneable.

public Foo implements Cloneable { 
    private String bar; 

    public Foo(Foo who) { 
    bar = who.bar; 
    } 

    public Object getClone() { 
    return new Foo(this); //Return new copy of self. 
    } 
} 
2
void set(int real) 
{ 
    this.real = real; 
} 

đây this là một từ khóa được sử dụng khi có biến dụ là tương tự như các biến địa phương.
sử dụng khác this là quá tải hàm tạo. nó có thể gọi hàm tạo trong một hàm tạo quá tải.

7

Người ta thường sử dụng từ khóa này trong rõ ràng constructor gọi. Bạn có thể xem ví dụ từ documentation.

public class Rectangle { 
    private int x, y; 
    private int width, height; 

    public Rectangle() { 
     this(0, 0, 1, 1); 
    } 
    public Rectangle(int width, int height) { 
     this(0, 0, width, height); 
    } 
    public Rectangle(int x, int y, int width, int height) { 
     this.x = x; 
     this.y = y; 
     this.width = width; 
     this.height = height; 
    } 
    ... 
} 
Các vấn đề liên quan