2009-11-29 41 views
15

tôi nghĩ Java có đánh giá ngắn mạch, tuy nhiên dòng này vẫn còn ném một con trỏ ngoại lệ null:Java ngắn mạch đánh giá

if((perfectAgent != null) && (perfectAgent.getAddress().equals(entry.getKey()))) { 

Trong trường hợp này perfectAgentnull, vì vậy tôi chỉ muốn toàn bộ biểu thức để trở false nhưng ứng dụng của tôi vẫn gặp sự cố trên dòng này với NullPointerException.

EDIT, phản ứng chung:

Kể từ perfectAgentnull, không có gì ở bên phải của && nên được thực thi, vì nó là không thể đối với sự biểu hiện đến mức khó tin. Thêm vào vấn đề, không thể thực hiện perfectAgent.getAddress()perfectAgent không chứa tham chiếu hợp lệ (nó là null và tất cả). Tôi đang cố gắng sử dụng đánh giá ngắn mạch để không phải kiểm tra null trong một tuyên bố riêng biệt mà làm cho logic cẩu thả hơn.

EDIT 2 (hoặc, tôi là một thằng ngốc): Vâng, giống như nhiều thứ trong cuộc sống, bạn tìm ra câu trả lời ngay sau khi thông báo với thế giới rằng bạn là một moron. Trong trường hợp này, tôi đã tắt tính năng tự động xây dựng của Eclipse trong khi thực hiện một việc khác và không bật lại, vì vậy tôi đã gỡ lỗi các tệp lớp không khớp với nguồn của tôi.

+6

Bạn đã kiểm tra mục nhập đó không phải là không? –

+0

Mục nhập không phải là rỗng. – Donnie

+1

Nếu 'perfectAgent' là' null' thì thực sự phần còn lại của dòng đó sẽ không được thực thi. Không thấy bất kỳ vấn đề với nó như bây giờ là:/ – Joey

Trả lời

4

nâng cao bài học gỡ lỗi # 1:

Nếu bạn chạy vào một lỗi dường như không thể (ví dụ như một trong những mâu thuẫn với bạn kiến ​​thức về Java), làm như sau:

  • Consult một văn bản có uy tín cuốn sách (hoặc tốt hơn vẫn còn, các tiêu chuẩn có liên quan) để xác nhận rằng sự hiểu biết của bạn không phải là thiếu sót. (Trong trường hợp này sự hiểu biết của bạn là chính xác, và bất kỳ sách giáo khoa bán rã nào sẽ xác nhận điều này trong một phút.)

  • Kiểm tra tất cả những điều ngu ngốc mà bạn có thể làm có thể gây ra lỗi không thể.Những thứ như không lưu tệp, không xây dựng hoàn chỉnh, chạy phiên bản cũ/cũ của ứng dụng, nằm trong thư mục sai, v.v.

Tóm lại, hãy học cách nghi ngờ bản thân nhiều hơn một chút.

2

Bạn đảm bảo rằng perfectAgent không phải là rỗng, do đó một hoặc nhiều perfectAgent.getAddress() hoặc entry hoặc entry.getKey() phải là rỗng. Hoặc getAddress() hoặc getKey() đang nhấn NPE trong quá trình triển khai.

Để gỡ lỗi loại điều này, hãy xem trước theo dõi ngăn xếp để ghim vị trí. Điều này sẽ cho bạn biết nếu nó xảy ra trong getAddress() hoặc trong getKey() hoặc trong đoạn mã được dán để gọi chúng. Tiếp theo, nếu nó nằm trong đoạn mã này, hãy thêm một số mã vào trước nếu if để kiểm tra là null. Bạn có thể sử dụng System.err.println() hoặc assertions cũ tốt. (Nếu bạn sử dụng các xác nhận, hãy đảm bảo bật chúng bằng cờ -enableassertions của lệnh java.)

Cập nhật: Vì vậy, diễn giải của tôi trở nên sai ... vấn đề đã trình bày hai sự kiện mâu thuẫn (có NPE trên dòng này, nhưng ngắn mạch nên đã xảy ra) và tôi tự động giả định thực tế đầu tiên là đúng và sai thứ hai khi thực tế nó là một vấn đề khác hoàn toàn do tắt tự động xây dựng trong Eclipse. Duh! Trong gỡ lỗi một cái gì đó "không thể" nó giúp để được triệt để hoài nghi.

7

Java không có đánh giá ngắn mạch. Có lẽ entrynull và do đó entry.getKey() đang gây ra NullPointerException. Một khả năng khác là getAddress() hoặc trả về null hoặc có một NullPointerException xảy ra bên trong một nơi nào đó (nếu nó phức tạp hơn một tuyên bố đơn giản return).

EDIT: Tôi thấy chỉnh sửa của bạn, nơi bạn khẳng định điều này:

Thêm vào điểm, nó là không thể thực hiện perfectAgent.getAddress() ...

Nhưng nếu perfectAgent.getAddress()được thực hiện thành công và trả lạinull? Hiểu ý tôi chứ...

0

Có ba tài liệu tham khảo khác hơn perfectAgent có thể được null:

  • perfectAgent.getAddress()
  • nhập
  • entry.getKey()

Nghỉ giải lao lên báo cáo kết quả hoặc chạy nó trong một trình gỡ lỗi.

+0

'entry.getKey()' là null sẽ không dẫn đến 'NullPointerException' trong đoạn mã của OP. – Asaph

+0

Object.equals (null) trả về false luôn. Vì vậy, nó sẽ không được entry.getKey() trả về null. Vì vậy, nó phải là một trong hai đầu tiên được liệt kê. –

+0

Ah vâng, cả hai đều chính xác. Chỉ có hai người đầu tiên là ứng cử viên. –

10

Nếu perfectAgent thực sự là không, mã sẽ không ném một ngoại lệ (ít nhất giả sử không có những điều kỳ lạ đang diễn ra, thay đổi từ không thành null sang nửa đường). Tôi sẽ hoàn toàn bị sốc nếu bạn có thể sản xuất một chương trình ngắn nhưng đầy đủ cho thấy nó làm như vậy.

Vì vậy, có, trực giác của bạn là đúng - đây không phải là vấn đề. Tìm nơi khác để tìm nguyên nhân. Tôi thật sự nghi ngờ rằng perfectAgentkhông phải là thực sự là vô hiệu và bạn đang gặp phải bất kỳ tình huống nào khác trong mã đó có thể gây ra ngoại lệ.

Tôi đề nghị bạn hãy thử trích đoạn mã đó ra thành một ví dụ ngắn nhưng đầy đủ - nếu bạn có thể làm như vậy, tôi sẽ ăn chiếc mũ ẩn dụ của mình; nếu không, bạn hy vọng sẽ tìm thấy vấn đề trong khi bạn cố gắng khai thác.

Điều gì khiến bạn nghĩ rằng perfectAgent thực sự không? Hãy thử chèn mã này trước mã:

if (perfectAgent == null) 
{ 
    System.out.println("Yup, it's null"); 
} 

Một khả năng rất, rất mỏng là bạn đã gặp lỗi JIT - nhưng tôi rất nghi ngờ điều đó.

+0

Ồ, vâng, tôi không nghĩ đó là lỗi JIT, chỉ cố gắng tìm ra những gì tôi đã làm sai. – Donnie

+0

Bạn không làm điều gì sai trong mã bạn đã hiển thị - ít nhất là không có gì gây ra điều này. Tôi nghi ngờ đó là một cái gì đó trong bất cứ điều gì dẫn bạn tin rằng perfectAgent là null :) –

+0

Xem Edit2 của tôi. Ngay trên mũi. – Donnie

1

Big mistery. Tôi đã sao chép dòng mã của bạn và thử nghiệm với perfectAgent == null, entry == null, entry.getKey() == null và các kết hợp của các mã đó: Không có NPE trong giường thử nghiệm của tôi (Java 1.6).

Bất kỳ lỗi gây phiền nhiễu nào, tôi nghi ngờ rằng nó có liên quan đến đánh giá ngắn mạch. Nếu đó là dòng này gây ra NPE, hơn, như xa như tôi có thể nói, perfectAgent không phải là null. Chúc may mắn và - cho chúng ta thấy lỗi khi bạn đã đánh bắt nó :)

0

Hãy thử định dạng mã của bạn như thế này:

if( 
    (perfectAgent != null) 
    && (
     perfectAgent.getAddress() 
     .equals(
     entry.getKey() 
    ) 
    ) 
) { 

Nó sẽ cho bạn một mục dòng stack trace tốt hơn.

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