2010-07-13 26 views
16

Tôi đang xem xét hướng dẫn sử dụng các phương pháp hay nhất và viết mã đề xuất java tôi nghĩ là đáng ngờ.Java: "xx" .equals (biến) tốt hơn variable.equals ("xx"), TRUE?

recomendation:

String variable; 

"xx".equals(variable) // OK 

variable.equals("xx") //Not recomended 

Bởi vì ngăn chặn sự xuất hiện của NullPointerException không được kiểm soát

là đúng này?

+3

Nếu bạn đang viết một hướng dẫn kỹ thuật, bạn có vấn đề ngữ pháp lớn hơn để lo lắng về hơn một báo nhỏ mã hóa như thế này. – Zak

+6

@Zak, điều đó không thực sự phù hợp. Làm thế nào để bạn biết hướng dẫn sẽ được bằng tiếng Anh? Có lẽ Xerg viết lưu loát bằng một số ngôn ngữ khác và đang tạo hướng dẫn bằng ngôn ngữ đó. Mọi người trả lời đều cố gắng tìm ra điểm mấu chốt của câu hỏi là gì. –

+1

Tôi không viết bất kỳ hướng dẫn nào. Tôi chỉ kiểm tra. Xin lỗi tiếng Anh của tôi, tôi là một người đọc tốt hơn nhà văn. – Xerg

Trả lời

23

Đây là một kỹ thuật rất phổ biến khiến thử nghiệm trả về false nếu biến là null thay vì ném một NullPointerException. Nhưng tôi đoán tôi sẽ khác nhau và nói rằng tôi sẽ không coi đây là một khuyến nghị mà bạn luôn luôn nên làm theo.

  • Tôi chắc chắn nghĩ rằng đó là điều mà tất cả các lập trình viên Java nên biết vì nó là một thành ngữ phổ biến.
  • Nó cũng là một kỹ thuật hữu ích để làm cho mã ngắn gọn hơn (bạn có thể xử lý các trường hợp null và không null cùng một lúc).

Nhưng:

  • Nó làm cho mã của bạn khó khăn hơn để đọc: "If blue is the sky..."
  • Nếu bạn vừa kiểm tra rằng lập luận của bạn là không null trên dòng trước đó thì nó là không cần thiết.
  • Nếu bạn quên thử nghiệm null và một người nào đó đi kèm với một đối số null mà bạn không mong đợi nó thì NullPointerException không nhất thiết là kết quả tồi tệ nhất có thể. Giả vờ tất cả mọi thứ là OK và thực hiện cho đến khi nó cuối cùng thất bại sau này không thực sự là một lựa chọn tốt hơn. Không nhanh là tốt.

Cá nhân tôi không nên sử dụng kỹ thuật này trong mọi trường hợp. Tôi nghĩ rằng nó nên được để lại cho bản án của lập trình viên trên cơ sở từng trường hợp cụ thể. Điều quan trọng là để đảm bảo rằng bạn đã xử lý các trường hợp null một cách thích hợp và làm thế nào bạn làm điều đó phụ thuộc vào tình hình. Kiểm tra việc xử lý đúng các giá trị null có thể là một phần của các nguyên tắc kiểm tra/kiểm tra mã.

+1

"Nó làm cho mã của bạn khó đọc hơn:" Nếu màu xanh là bầu trời ... "- còn được gọi là điều kiện yoda - http: // vi.wikipedia.org/wiki/Yoda_conditions – chrismarx

10

Điều đó đúng. Nếu variablenull trong ví dụ của bạn,

variable.equals("xx"); 

sẽ ném một NPE vì bạn không thể gọi một phương thức (equals) trên một đối tượng null. Nhưng

"xx".equals(variable); 

sẽ chỉ trả lại false không có lỗi.

+0

Nhưng 'biến' là' null' có thể là một lỗi. –

+0

@Tom: tốt, có thể. Tôi đã chạy vào các tình huống mà trong đó nó phải là một lỗi và nhiều tình huống khác mà nó không nên. Tôi thực sự đồng ý với Mark Byers rằng nó có ý nghĩa để đánh giá nó trên cơ sở từng trường hợp cụ thể. –

3

Đây là một kỹ thuật phổ biến được sử dụng trong các chương trình Java (và C#). Biểu mẫu đầu tiên tránh ngoại lệ con trỏ null vì phương thức .equals() được gọi trên chuỗi không đổi "xx", không bao giờ là rỗng. Một chuỗi không null so với null là false.

Nếu bạn biết rằng variable sẽ không bao giờ là rỗng (và chương trình của bạn không chính xác theo cách nào đó nếu nó không bao giờ trống), thì sử dụng variable.equals("xx") là tốt.

4

Thực ra, tôi nghĩ rằng đề xuất ban đầu là đúng sự thật. Nếu bạn sử dụng variable.equals("xx"), thì bạn sẽ nhận được NullPointerException nếu variable là không. Đặt chuỗi liên tục ở phía bên trái tránh được khả năng này.

Điều đó tùy thuộc vào bạn liệu biện pháp phòng thủ này có đáng để đánh giá nỗi đau của những gì nhiều người coi là thành ngữ không tự nhiên hay không.

+1

Peronsalized Tôi tìm thấy "phiên bản Yoda" rất khó xử để đọc, nhưng nó thực sự tránh ngoại lệ con trỏ null. Phương án thay thế là 's! = Null && s.equals ("xx")', có nhiều thứ để nhập và mất thêm vài nano giây để so sánh thêm. – Jay

0

Nếu bạn cần kiểm tra null, tôi thấy điều này dễ đọc hơn if (variable != null && variable.equals("xx")). Đó là một vấn đề sở thích cá nhân hơn.

2

Đúng là sử dụng bất kỳ phần nào của đối tượng theo cách đó sẽ giúp bạn tránh được NPE.

Nhưng đó là lý do tại sao chúng tôi có Ngoại lệ, để xử lý những điều đó.

Có thể nếu bạn sử dụng "xx" .equals (biến), bạn sẽ không bao giờ biết nếu giá trị của biến là null hoặc chỉ không bằng "xx". IMO tốt nhất nên biết rằng bạn đang nhận được một giá trị null trong biến của bạn, vì vậy bạn có thể reasign nó, thay vì chỉ bỏ qua nó.

0

Bạn chính xác về thứ tự của séc - nếu biến là null, hãy gọi .equals trên chuỗi hằng số sẽ ngăn chặn NPE - nhưng tôi không chắc tôi coi đây là một ý tưởng hay; Cá nhân tôi gọi nó là "slop".

Slop là khi bạn không phát hiện một điều kiện bất thường nhưng trên thực tế tạo thói quen để cá nhân tránh nó phát hiện. Việc truyền xung quanh một null dưới dạng một chuỗi trong một khoảng thời gian dài sẽ dẫn đến các lỗi có thể bị che khuất và khó tìm.

Mã hóa cho slop đối diện với "Thất bại nhanh không thành công". Sử dụng một null như một chuỗi đôi khi có thể làm cho một giá trị "đặc biệt" tuyệt vời, nhưng thực tế là bạn đang cố gắng so sánh nó với một cái gì đó chỉ ra rằng sự hiểu biết của bạn về hệ thống là không đầy đủ (tốt nhất) - bạn càng sớm càng tốt tìm ra thực tế này, càng tốt.

Mặt khác, làm cho tất cả các biến cuối cùng theo mặc định, sử dụng Generics và giảm thiểu khả năng hiển thị của tất cả các đối tượng/phương pháp là thói quen làm giảm slop.

0

Như một mặt lưu ý, đây là một mẫu thiết kế nơi mã khuyến nghị này có thể không thực hiện bất kỳ sự khác biệt, kể từ khi String (tức là Optional<String>) không bao giờ được null vì của cuộc gọi .isPresent() từ các mẫu thiết kế:

Optional<String> gender = Optional.of("MALE"); 
if (gender.isPresent()) { 
    System.out.println("Value available."); 
} else { 
    System.out.println("Value not available."); 
} 
gender.ifPresent(g -> System.out.println("Consumer: equals: " + g.equals("whatever"))); 
Các vấn đề liên quan