如何在运行时检查子类是否是类的实例?

iam*_*sed 68 java subclass instanceof

在Android应用程序测试套件中,我有一个这样的类,其中B是一个视图:

public class A extends B {
... etc...
}
Run Code Online (Sandbox Code Playgroud)

现在我有一个可能包含A对象的视图对象列表,但在这种情况下我只关心它们是子类还是"实例" B.我想做点什么:

ArrayList<View> viewList = getViews();
Iterator<View> iterator = viewList.iterator();
while (iterator.hasNext() && viewList != null) {
    View view = iterator.next();
    if (view.getClass().isInstance(B.class)) {
        // this is an instance of B
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,当if遇到一个A对象时,它不会评估为"实例B".有办法做isSubclassOf什么吗?

Har*_*ded 155

您必须仔细阅读此方法的API.有时你很容易混淆.

它是:

if (B.class.isInstance(view))
Run Code Online (Sandbox Code Playgroud)

API表示:确定指定的Object (参数)是否与此Class 表示的对象(您调用方法的类对象)分配兼容

要么:

if (B.class.isAssignableFrom(view.getClass()))
Run Code Online (Sandbox Code Playgroud)

API表示:确定此Class对象表示的类或接口是否与指定的Class参数表示的类或接口相同,或者是它们的超类或超接口

或(没有反思和推荐的):

if (view instanceof B)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,由于擦除,`instanceof`不适用于泛型. (11认同)
  • +1的if(查看实例B).简单而有效. (9认同)
  • 说实话,我甚至不认为Java的泛型是真正的泛型; Java的泛型只是用于类型安全的语法糖(或者更重要的是,执行).它们纯粹是编译时间,我认为大多数人来自C++和随后的模板将很难掌握擦除的概念. (3认同)

Kri*_*ris 24

if(view instanceof B)
Run Code Online (Sandbox Code Playgroud)

如果view是B的实例或子类A(或者B的任何子类),则返回true.

  • 我想提一下,必须在当前的.java文件中导入B才能使其正常工作.Eclipse会将该行标记为有错误但不提供任何有用的解决方案(在实现我之前没有导入类文件之前浪费了将近一个小时尝试不同的语法.)对于任何想知道的人,正确的语法是((实例名称)instanceof (班级名称)).单词class不会出现在其中的任何位置. (3认同)

Joa*_*uer 10

也许我错过了什么,但这不够:

if (view instanceof B) {
    // this view is an instance of B
}
Run Code Online (Sandbox Code Playgroud)


Mic*_*rdt 6

Class.isAssignableFrom() - 也适用于接口.如果你不想那样,你必须打电话getSuperclass()和测试,直到你到达Object.