2015-09-14 31 views
6

Tôi có một chức năng lọc danh sách một số giá trị và nó sử dụng instanseof xây dựng:lớp như là đối số chức năng

public static List<View> getAllChildren(View v) { 
    /* ... */ 
    if (v instanceof Button) { 
     resultList.add(v); 
    } 
    /* ... */ 
} 

tôi muốn làm cho nó tổng quát hơn và thiết lập nút như chức năng tham số:

public static List<View> getAllChildren(View v, ? myClass) { 
    /* ... */ 
    if (v instanceof myClass) { 
     resultList.add(v); 
    } 
    /* ... */ 
} 

Nhưng tôi không biết làm thế nào để vượt qua myClass với chức năng. Xin vui lòng cho tôi biết làm thế nào tôi có thể khái quát hóa chức năng này?

Trả lời

8

Bạn có thể chuyển loại lớp dưới dạng tham số bằng cách sử dụng lớp Class. Lưu ý rằng đó là một loại chung. Ngoài ra, các nhà điều hành instanceof chỉ hoạt động trên các loại tài liệu tham khảo, vì vậy bạn sẽ phải lật nó xung quanh để có được điều này để làm việc:

public static List<View> getAllChildren(View v, Class<?> myClass) { 
    /* ... */ 
    if (myClass.isInstance(v)) { 
     resultList.add(v); 
    } 
    /* ... */ 
} 

Để có được loại Class để được thông qua tại như thế này, bạn chỉ có thể sử dụng tên của lớp bạn muốn, với ".class" được thêm vào. Ví dụ, nếu bạn muốn gọi phương pháp này với lớp Button, bạn sẽ làm điều đó như sau:

getAllChildren(view, Button.class); 

Hoặc nếu bạn có một thể hiện của một cái gì đó mà bạn muốn loại, bạn sẽ sử dụng phương pháp getClass() :

Button b = new Button(); 
getAllChildren(view, b.getClass()); 

theo Evan LaHurd đề cập trong một chú thích, isInstance() sẽ kiểm tra xem hai lớp là nhiệm vụ tương thích, vì vậy họ có thể không cùng lớp chính xác. Nếu bạn muốn chắc chắn rằng họ đang chính xác cùng lớp, bạn có thể kiểm tra chúng đối với bình đẳng như vậy:

myClass.equals(v.getClass()); 

hoặc

myClass == v.getClass(); 

cũng sẽ làm việc trong trường hợp này, như đã chỉ ra bởi bayou.io

+1

Tôi cũng sẽ đề cập đến cách bạn nhận đối tượng 'Lớp ' (ví dụ: 'Button.class') –

+0

@PaulBoddington Điểm tốt. Tôi sẽ chỉnh sửa điều đó. – gla3dr

+1

Cũng đáng chú ý là 'myClass.isInstance (v)' sẽ trả về true nếu 'v' tương ứng với' myClass'. Nó không nhất thiết phải là cùng một lớp. Nếu bạn muốn kiểm tra xem đó có phải là cùng một lớp, thì bạn có thể làm 'myClass.equals (v.getClass())'. –

3

Nếu bạn cần linh hoạt hơn, bạn có thể thực hiện phương pháp getAllChildren bạn chấp nhận bất kỳ bộ lọc sử dụng Java 8 lambdas:

import java.util.function.*; 
class Test { 
    public static void main(String... args) { 
     check(new Integer(1), o -> o instanceof Integer); 
     // Prints "That's it". 
     check(new Boolean(true), o -> o instanceof Integer); 
     // Prints "That's not it". 
    } 

    static void check(Object o, Predicate<Object> check) { 
     if (check.test(o)) 
      System.out.println("That's it"); 
     else 
      System.out.println("That's not it"); 
    } 
} 

Hoặc sử dụng mẫu Chiến lược nếu bạn muốn, hoặc nếu Java 8 không khả dụng.

Vì mục đích của bạn, giải pháp gla3dr có thể là tốt nhất, nhưng nếu bạn cần THÊM POWER xem xét các tùy chọn này.

+1

'Integer.class :: isInstance' hoặc' o-> o instanceof Integer' :) – ZhongYu

+0

Cảm ơn. Tôi đã không thực sự quen thuộc với sự khác biệt, vì vậy tôi chỉ cần sao chép từ gla3dr. Đọc lên trên nó, có vẻ như 'instanceof' là thông thường hơn khi loại được biết tại thời gian biên dịch, vì vậy tôi đã chỉnh sửa câu trả lời của tôi. – DavidS

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