2010-04-19 25 views
18

Tôi biết tôi có thể tìm hiểu xem một biến là null trong Java sử dụng những kỹ thuật này:Tìm hiểu những gì biến được ném một NullPointerException lập trình

  • nếu (var==null) -> quá nhiều việc
  • try { ... } catch (NullPointerException e) { ...} -> nó nói tôi biết dòng được ném ngoại lệ
  • sử dụng trình gỡ lỗi -> bằng tay, quá chậm

xem xét dòng mã này:

if (this.superSL.items.get(name).getSource().compareTo(VIsualShoppingList.Source_EXTRA)==0) { 

Tôi muốn biết nếu có một cách chung chung để tìm ra chương trình nào biến (không chỉ là dòng) là ném NullPointerException trong một khu vực nhất định của mã. Trong ví dụ này, biết rằng

+5

Hm, nó sẽ dễ dàng hơn để tìm NullPointerException nếu điều này wasn 't một lớp lót. Thật khó để làm theo mã như vậy. –

+10

Xem xét các tùy chọn của bạn, tôi chỉ cho rằng "quá nhiều công việc" có thể thực sự có nghĩa là ít công việc hơn trong thời gian dài. –

+3

Biến điều này thành một khối thích hợp. Bạn sẽ tìm thấy vấn đề trong thời gian không. – Geo

Trả lời

25

Kể từ khi nó có thể gây ra một con trỏ ngoại lệ rỗng mà không hề liên quan đến một biến:

throw new NullPointerException(); 

tôi sẽ phải nói rằng không có cách nào tổng quát để pin xuống một con trỏ ngoại lệ null để một biến cụ thể.

Đặt cược tốt nhất của bạn sẽ là đặt càng ít càng tốt các câu lệnh trên mỗi dòng để nó trở nên rõ ràng những gì gây ra ngoại lệ con trỏ null. Xem xét sắp xếp lại mã của bạn trong câu hỏi để trông giống như sau:

List items = this.superSL.items; 
String name = items.get(name); 
String source = name.getSource(); 
if (source.compareTo(VIsualShoppingList.Source_EXTRA) == 0) { 
    // ... 
} 

Đó là nhiều dòng mã hơn để chắc chắn. Nhưng nó cũng dễ đọc hơn và dễ bảo trì hơn.

+0

có các ngôn ngữ có thể cho bạn biết biến nào chịu trách nhiệm không? (hoặc IDE)? – ycomp

1

Tôi biết bạn đã đề xuất rằng (var==null) là quá nhiều việc, nhưng như Miguel đã nêu trong các nhận xét, đó là những gì tôi sẽ làm.

2

Bạn có ý nghĩa gì khi "sử dụng trình gỡ lỗi -> bằng tay, quá chậm"? Nếu mã của bạn được cấu trúc đúng cách, thì sẽ không có nhiều hơn hai hoặc ba biến được sử dụng trên cùng một dòng. Có quá chậm để kiểm tra chúng không? Bạn không có NullPointers mỗi phút.

+1

> Ý bạn là gì khi "sử dụng trình sửa lỗi -> bằng tay, quá chậm"? - Ví dụ: từ kinh nghiệm của tôi, khi bạn phải gỡ lỗi từ xa. Nhưng đôi khi tập tin đính kèm gỡ lỗi từ xa thậm chí không thể. – gumkins

6

Xin lỗi, không, không có cách lập trình đơn giản để xác định biến hoặc cuộc gọi phương thức nào là nguồn gốc của ngoại lệ. Bạn có thể sử dụng một cái gì đó như Aspect-Oriented Programming (AOP), ví dụ: AspectJ, nhưng điều này không phải là vốn có của ngôn ngữ và thường không được kết hợp vào một chương trình chỉ đơn giản là cho các mục đích gỡ lỗi.

  • if (var==null) -> too much work
  • try { } catch() { }
  • Debugger

Tôi biết bạn không muốn nghe điều này, nhưng đây là những cách đơn giản các chi phí kinh doanh.

if (this.superSL.items.get(name).getSource().compareTo(VIsualShoppingList.Source_EXTRA)==0) { 

Thật không bình thường khi thấy có quá nhiều cuộc gọi cùng nhau. Tôi tin rằng bạn đặt cược tốt nhất là để có được trong thói quen phá vỡ này lên nhiều hơn - không cần thiết xuống đến 1 cuộc gọi trên mỗi dòng, nhưng ít hơn này. Tại sao?

1) Correctness - có hợp lệ trong thiết kế cho một trong các cuộc gọi này để trả về giá trị không?Nếu vậy, bạn nên phá vỡ nó ra, kiểm tra nó, và xử lý nó một cách thích hợp.

2) Understandability - sẽ dễ dàng hơn cho những người bảo trì trong tương lai (bao gồm tương lai bạn) để hiểu các biến trung gian, được đặt tên để giúp làm rõ những gì đang xảy ra trên dòng này.

3) Efficiency - thường khi bạn đi sâu vào biểu đồ (chuỗi cùng một chuỗi các cuộc gọi phương thức), có khả năng bạn sẽ cần phải quay lại sau đó. Việc giữ giá trị trung gian này trong một biến trung gian có nghĩa là tránh thực hiện một hoặc nhiều cuộc gọi phương thức một lần nữa.

4) Debugging - như được chỉ ra bởi câu hỏi của bạn, tách một dòng phức tạp như thế này sẽ đơn giản hóa việc gỡ lỗi. bằng cách thu hẹp nguồn có thể có của ngoại lệ.

1

Tôi nghĩ bạn nên thông báo Demeters Law.

Không có nhiều người theo dõi nó một cách nghiêm túc, bởi vì nó dẫn đến rất nhiều phương pháp đại biểu.
Nhưng nhận được quá xa nó sẽ dẫn đến sự phụ thuộc vào cấu trúc bên trong cần được minh bạch.

+2

Chỉ vì nội dung được kết hợp với nhau, không có nghĩa là Luật Demeter vi phạm của bạn. Đó là chủ yếu khi bạn đang lấy một tham chiếu thông qua chuỗi, sau đó sửa đổi một cái gì đó. Không có gì sai khi tiếp cận để hiển thị hoặc so sánh giá trị theo kiểu chỉ đọc. –

0

Điều gì đã làm việc thực sự tuyệt vời với tôi là bắt ngoại lệ, nơi nó thường bị ném và sau đó sử dụng Đăng nhập để xem liệu có giá trị nào trong số đó có giá trị 'không'.

Mã của tôi:

try { 
       if (description_visible) advice_title_cur.setText(all_title_array[pos]); 
       else advice_title_cur.setText(all_title_array[pos] + "..."); 

      } catch (NullPointerException e) { 
       e.printStackTrace(); 
       Log.e("My name", "description_visible " + description_visible); 
       Log.e("My name", "advice_title_cur " + advice_title_cur); 
       Log.e("My name", "all_title_array " + all_title_array); 
       Log.e("My name", "pos " + pos); 
      } 
Các vấn đề liên quan