2012-09-11 27 views
6

Điều này có nghĩa là lớp đã được khởi tạo, nhưng các biến không được đặt.Cách tốt nhất để biết tất cả các biến trong một lớp là null?

Một mẫu Class:

public class User { 

    String id = null; 
    String name = null; 

    public String getId() { 
     return id; 
    } 
    public void setId(String id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
} 

Lớp thực tế là rất lớn mà tôi không muốn kiểm tra xem (xyz == null) cho mỗi biến.

+0

Bạn có thể sử dụng phản chiếu – 0xSina

+2

'if (id == null)' là phương pháp * tốt nhất *. – adatapost

+0

Các trường tham chiếu được khởi tạo thành giá trị mặc định của chúng, 'null', trong trường hợp không có bộ khởi tạo rõ ràng. – oldrinb

Trả lời

6

Hãy thử một cái gì đó như thế này:

public boolean checkNull() throws IllegalAccessException { 
    for (Field f : getClass().getDeclaredFields()) 
     if (f.get(this) != null) 
      return false; 
    return true;    
} 

Mặc dù nó có lẽ sẽ tốt hơn để kiểm tra mỗi biến nếu có khả thi.

+0

Hiệu suất khôn ngoan, là điều này xa phía sau phương pháp 'if (variable == null)'? – th3an0maly

+0

Có, nó sẽ mất nhiều thời gian hơn 'if (var == null)'. – arshajii

+0

trông giống như một hack tốt đẹp –

4

"Tốt nhất" là một thuật ngữ chủ quan :-)

Tôi chỉ sử dụng phương pháp kiểm tra từng biến riêng lẻ. Nếu lớp của bạn đã có rất nhiều trong số này, các tăng kích thước sẽ không thể là nhiều nếu bạn làm điều gì đó như:

public Boolean anyUnset() { 
    if ( id == null) return true; 
    if (name == null) return true; 
    return false; 
} 

Miễn là bạn giữ cho mọi thứ theo thứ tự, thay đổi mã (và tự động kiểm tra với một kịch bản nếu bạn đang hoang tưởng) sẽ tương đối không đau. Ngoài ra, bạn có thể đặt các giá trị này vào bản đồ của một số loại (ví dụ: HashMap) và chỉ giữ một danh sách các tên khóa cho danh sách đó. Bằng cách đó, bạn có thể lặp qua danh sách các phím, kiểm tra xem các giá trị có được đặt chính xác hay không.

+1

Nhưng nếu tôi làm điều này, tôi sẽ phải chỉnh sửa phương pháp mỗi khi tôi thêm một trường vào lớp. Bên cạnh đó, một phương pháp chung có thể được đặt trong một lớp trừu tượng và mở rộng để được sử dụng trong tất cả các đối tượng giá trị khác – th3an0maly

+3

Có, bạn sẽ. Tôi không chắc tại sao bạn nghĩ đó là một vấn đề. Bạn _know_ những lĩnh vực bạn đang thêm, bạn phải tạo setters và getters cho họ. Việc thêm một dòng kiểm tra bổ sung đơn giản không phải là nhiều công việc phụ. – paxdiablo

+0

Tôi nghĩ OP có nghĩa là "Cách dễ nhất, hiệu quả nhất" là gì. Nếu đó là trường hợp thì đây là, theo ý kiến ​​cá nhân của tôi, một câu trả lời khủng khiếp – gromit190

1
Field[] field = model.getClass().getDeclaredFields();  

for(int j=0 ; j<field.length ; j++){  
      String name = field[j].getName();     
      name = name.substring(0,1).toUpperCase()+name.substring(1); 
      String type = field[j].getGenericType().toString();  
      if(type.equals("class java.lang.String")){ 
       Method m = model.getClass().getMethod("get"+name); 
       String value = (String) m.invoke(model);  
       if(value == null){ 
        ... something to do... 
       } 
} 
1

Cách tốt nhất theo ý kiến ​​của tôi là Phản ánh như những người khác đã đề xuất. Đây là một mẫu đánh giá từng trường cục bộ cho null. Nếu nó tìm thấy một trong đó không phải là null, phương thức sẽ trả về false.

public class User { 

    String id = null; 
    String name = null; 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public boolean isNull() { 
     Field fields[] = this.getClass().getDeclaredFields(); 
     for (Field f : fields) { 
      try { 
       Object value = f.get(this); 
       if (value != null) { 
        return false; 
       } 
      } 
      catch (IllegalArgumentException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      catch (IllegalAccessException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 


     } 
     return true; 

    } 

    public static void main(String args[]) { 
     System.out.println(new User().allNull()); 
    } 
} 
15

Một giải pháp không phản chiếu cho Java 8, trong dòng paxdiabo's answer nhưng mà không sử dụng một loạt các if 's, sẽ được xem tất cả các lĩnh vực và kiểm tra nullness:

return Stream.of(id, name) 
     .allMatch(Objects::isNull); 

này vẫn còn khá dễ dàng để duy trì trong khi tránh sự phản chiếu búa.

+0

Có cách nào để lấy các giá trị trường ví dụ: Stream.of (id, name), loại bỏ các trường rỗng và trả về Danh sách các giá trị của các trường rỗng không –

+0

@Bạn có thể sử dụng 'filter()' nhưng đó là một câu hỏi khác nó có thể đã được yêu cầu trên SO. –

+0

cảm ơn cho bình luận, ya đó là câu hỏi khác nhau nhưng bạn có thể vui lòng cho tôi biết làm thế nào để làm điều đó như tôi đang mắc kẹt với một vấn đề và không thể tìm thấy giải pháp hiệu quả. –

1

Nó cũng có thể được thực hiện mà không cần sử dụng sự phản chiếu.

Giải pháp là động. Khi lớp của bạn được mở rộng với các trường mới, bạn không cần phải thêm chúng vào danh sách hoặc thêm một kiểm tra null khác.

Lưu ý:

Tôi đã sử dụng chú thích EqualsAndHashCode bởi Lombok.

Bạn phải đảm bảo hàm tạo mặc định không được thực hiện với hành vi tùy chỉnh và trường của bạn không có giá trị mặc định khác với giá trị mặc định java được tích hợp sẵn (null cho kiểu tham chiếu, 0 cho int, v.v.).

@EqualsAndHashCode 
public class User 
{ 
    private static User EMPTY = new User(); 

    private String id = null; 
    private String name = null; 

    private User() 
    { 
    } 

    public User(String id, String name) 
    { 
     this.id = id; 
     this.name = name; 
    } 

    public String getId() { 
     return id; 
    } 
    public void setId(String id) { 
     this.id = id; 
    } 

    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 

    public boolean isEmpty() 
    { 
     return this.equals(EMPTY); 
    } 
} 
Các vấn đề liên quan