Kiểm tra nếu đối tượng thực hiện giao diện


149

Điều này có thể đã được hỏi trước đây, nhưng một tìm kiếm nhanh chỉ đưa ra cùng một câu hỏi được yêu cầu cho C #. Xem ở đây.

Những gì tôi về cơ bản muốn làm là kiểm tra thời tiết một đối tượng cụ thể thực hiện một giao diện nhất định.

Tôi đã tìm ra một giải pháp nhưng điều này không đủ thoải mái để sử dụng nó thường xuyên trong các câu lệnh if hoặc case và tôi đã tự hỏi rằng Java không có giải pháp tích hợp.

public static Boolean implementsInterface(Object object, Class interf){
    for (Class c : object.getClass().getInterfaces()) {
        if (c.equals(interf)) {
            return true;
        }
    }
    return false;
}


EDIT: Ok, cảm ơn câu trả lời của bạn. Đặc biệt với Damien Pollet và Noldorin, bạn đã khiến tôi suy nghĩ lại về thiết kế của mình để tôi không thử nghiệm các giao diện nữa.


3
Bạn không thể thử truyền và bắt ngoại lệ nếu một lỗi bị ném (hoặc kiểm tra kết quả null thậm chí, nếu Java có bất cứ điều gì gây khó chịu cho toán tử "dưới dạng" C #) không? Tôi là một lập trình viên C # chứ không phải là một Java, vì vậy tôi chủ yếu chỉ đoán ở đây, mặc dù tôi nghĩ cách tiếp cận như vậy sẽ có thể thực hiện được trong bất kỳ ngôn ngữ OO nào.
Noldorin

1
Ném ngoại lệ là thực hành tốt trong trường hợp này chỉ khi bạn không phải quan tâm đến hiệu suất.
Rafa

1
Xin lỗi, nhưng những câu trả lời đó khiến bạn nghĩ lại thiết kế của bạn ở đâu? Ngay cả khi họ xóa, họ là gì? Bạn có thể vui lòng giúp tôi @sebastiangeiger
ozanmuyes

1
@ozanmuyes Tôi xin lỗi, tôi đã không viết Java trong hơn 4 năm và thật không may là tôi không thể nhớ những gì tôi đã làm.
sebastiangeiger

Câu trả lời:


191

Người instanceofvận hành thực hiện công việc một NullPointerExceptioncách an toàn. Ví dụ:

 if ("" instanceof java.io.Serializable) {
     // it's true
 }

mang lại sự thật Từ:

 if (null instanceof AnyType) {
     // never reached
 }

mang lại sai, instanceoftoán tử là null an toàn (mã bạn đã đăng không).

instanceof là sự thay thế an toàn trong thời gian biên dịch được tích hợp sẵn cho Class # isInstance (Object)


5
instanceof chỉ hoạt động trên lớp chữ mặc dù. Vì vậy, nó không thể được sử dụng trong trường hợp của OP
LordOfThePigs

chắc chắn, nó là thời gian biên dịch an toàn; và đó là cách tích hợp và đó là đối số của câu hỏi (imho)
dfa

@LordOfThePigs không có. Nó kiểm tra nếu một giao diện được thực hiện tốt.
NimChimpsky

5
@NimChimpsky: bạn đã hiểu nhầm quan điểm của tôi. Lớp chữ là khi bạn viết những thứ như MyClass.classhoặc MyInterface.classtrong mã nguồn của bạn. Các chữ theo lớp có thể tham chiếu đến các lớp, giao diện và các kiểu nguyên thủy và sẽ trả về một thể hiện tương ứng của lớp Class. Quan điểm của tôi là OP không sử dụng một lớp chữ, nhưng thay vào đó là một thể hiện của lớp Class, và thật không may, toán tử phía bên phải của instanceoftừ khóa phải là một lớp chữ, không phải là một thể hiện của lớp Class.
LordOfThePigs

@dsdsdsdsd Vì bài đăng này tôi thậm chí không nghe / đọc về nó, nhưng sau khi tìm kiếm trên Google, tôi đã hiểu ra nó là tên viết tắt của Null Pulum Exception.
ozanmuyes

42

Điều này nên làm:

public static boolean implementsInterface(Object object, Class interf){
    return interf.isInstance(object);
}

Ví dụ,

 java.io.Serializable.class.isInstance("a test string")

đánh giá để true.


8

Tôi thích instanceof:

if (obj instanceof SomeType) { ... }

đó là phổ biến hơn và dễ đọc hơn SomeType.isInstance(obj)


5
Hãy nhớ rằng đó if (obj instanceof SomeType) { ... }là tĩnh (nghĩa là - nó không thể thay đổi khi chạy) và SomeType.isInstance(obj)là động.
Tomasz Bielaszewski


3

Nếu bạn muốn kiểm tra giao diện:

public List<myType> getElement(Class<?> clazz) {
    List<myType> els = new ArrayList<myType>();
    for (myType e: this.elements.values()) {
        if (clazz.isAssignableFrom(e.getClass())) {
            els.add(e);
        }
    }
    return els;

}

clazz là một Giao diện và myType là Loại mà bạn đã xác định có thể triển khai một số giao diện. Với mã này, bạn chỉ nhận được các loại thực hiện giao diện đã xác định


1

Tôi đã gặp vấn đề này tối nay với Android và sau khi xem các giải pháp javadoc, tôi đã tìm ra giải pháp làm việc thực sự này chỉ dành cho những người như tôi cần nhiều hơn một lời giải thích javadoc.

Đây là một ví dụ hoạt động với giao diện thực tế sử dụng java java. Nó kiểm tra hoạt động được gọi là đã triển khai giao diện AboutDialogListener trước khi thử truyền trường AboutDialogListener.

public class About extends DialogFragment implements OnClickListener,
    OnCheckedChangeListener {

public static final String FIRST_RUN_ABOUT = "com.gosylvester.bestrides.firstrunabout";


public interface AboutDialogListener {
    void onFinishEditDialog(Boolean _Checked);
}

private AboutDialogListener adl;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    Activity a = this.getActivity();
    if (AboutDialogListener.class.isInstance(a)) {
        adl = (AboutDialogListener) a;
        }
}

... Sau này tôi kiểm tra xem trường adl có phải không! Trước khi gọi giao diện

@Override
public void onStop() {
    super.onStop();
    sharedPref.edit().putBoolean(About.FIRST_RUN_ABOUT, _Checked).commit();
    // if there is an interface call it.
    if (adl != null) {
        adl.onFinishEditDialog(is_Checked());
    }
}

0

Với ArrayUtils Apache commons-lang, hãy xem giao diện bạn yêu cầu có được chứa trong các giao diện của đối tượng bạn không

public static Boolean implementsInterface(Object object, Class interf){
    return ArrayUtils.contains(object.getClass().getInterfaces(), interf);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.