如何确定一个对象的类?

car*_*ier 487 java inheritance

如果类B和类C扩展类A并且我有一个类型的对象,B或者C我如何确定它是一个实例的类型?

IAd*_*ter 769

if (obj instanceof C) {
//your code
}
Run Code Online (Sandbox Code Playgroud)

  • 我相信getClass()方法是原始问题的答案.在这种情况下(obj instanceof A)也会给出"true"输出,但目的是找到图片中对象的运行时类.如果Parent1由Child1和Child2扩展,请尝试以下`code` Child1 child1 = new Child1(); Parent1 parentChild = new Child2(); Child2 child2 = new Child2(); (child1 instanceof Parent1); (child1 instanceof Child1); (parentChild instanceof Child2); (parentChild instanceof Parent1); (parentChild instanceof Child1); `code`,它可以清除instanceof的意图. (31认同)
  • 注意反向检查或如何检查Object是否不是类的实例是有用的:`if(!(obj instanceof C))` (29认同)
  • 如果我有两个类实现单个接口怎么办?如何区分对象的确切类? (3认同)
  • 不过有一件事,如果obj为null则不起作用。解决方案将是ParentInterface.class.isAssignableFrom(Child.class) (3认同)

Bil*_*ard 333

使用Object.getClass().它返回对象的运行时类型.

  • 这实际上就是你如何确定一个对象的类 (11认同)
  • 不知道为什么这不是最受欢迎的答案 (3认同)

icz*_*cza 165

提出了多个正确的答案,但还有更多的方法:Class.isAssignableFrom()并且只是试图转换对象(可能会抛出一个ClassCastException).

总结的可能方式

让我们总结一下测试对象obj是否是类型实例的可能方法C:

// Method #1
if (obj instanceof C)
    ;

// Method #2
if (C.class.isInstance(obj))
    ;

// Method #3
if (C.class.isAssignableFrom(obj.getClass()))
    ;

// Method #4
try {
    C c = (C) obj;
    // No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}

// Method #5
try {
    C c = C.class.cast(obj);
    // No exception: obj is of type C or IT MIGHT BE NULL!
} catch (ClassCastException e) {
}
Run Code Online (Sandbox Code Playgroud)

null处理上的差异

null但处理方式有所不同:

  • 在第2种方法表达式求值false,如果objnull(null不是任何实例).
  • 第三种方法NullPointerException显然会抛出.
  • 相反,第4和第5种方法接受null因为null可以投射到任何类型!

要记住:null 不是任何类型的实例,但它可以转换为任何类型.

笔记

  • Class.getName()不应该用来执行"is-instance-of"测试,因为如果对象不是类型C而是它的子类,它可能有一个完全不同的名称和包(因此类名显然不匹配)但它是仍然是类型C.
  • 出于同样传承的原因Class.isAssignableFrom()是不是对称的:
    obj.getClass().isAssignableFrom(C.class)将返回false如果类型obj是一个子类C.

  • 这是对不同方法中许多陷阱的非常好的总结.谢谢你这么完整的写作! (6认同)

Joh*_*iss 31

您可以使用:

Object instance = new SomeClass();
instance.getClass().getName(); //will return the name (as String) (== "SomeClass")
instance.getClass(); //will return the SomeClass' Class object
Run Code Online (Sandbox Code Playgroud)

HTH.但我认为大多数时候,将它用于控制流程或类似的东西是不好的做法......


Yuv*_*dam 24

使用任何建议的方法都被认为是基于不良OO设计的代码气味.

如果你的设计很好,你不应该发现自己需要使用getClass()instanceof.

任何建议的方法都可以做到,但在设计方面需要牢记.

  • 此外,我会说,如果没有解释确切原因,或者提及纸张,书籍或任何其他解释问题的资源被认为不具有建设性,那么告诉人们有些不好.因此,知道我在StackOverflow中,我不知道为什么人们对这个答案的评价如此之多.这里发生了一些变化...... (57认同)
  • 不是nessecarily.有时候接口分离是好的.有时你想知道A是否是B,但是你不想强制要求A是B,因为大多数功能只需要A - B具有可选功能. (27认同)
  • 此外,有时您需要确保对象与您要比较的同一个类; 例如,当我创建自己的类时,我喜欢覆盖Object的equals方法.我总是验证进入的对象属于同一类. (8认同)
  • 是的,使用多态方法调用可以避免99%的getClass和instanceof使用. (3认同)
  • 我同意了.在这种情况下,我正在处理从xml生成的对象,其后面是一个设计不良的架构,我没有所有权. (3认同)
  • 序列化,获取类型等一些任务可能是最简单的方法吗? (2认同)

小智 15

在这种情况下我们可以使用反射

objectName.getClass().getName();
Run Code Online (Sandbox Code Playgroud)

例:-

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String name = request.getClass().getName();
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您将获得对象传递给HttpServletRequest接口引用变量的类的名称.


And*_*son 13

.isInstance" Class"类上还有一个方法.如果你通过你得到一个对象的类,myBanana.getClass()你可以看到你的对象myApple是否是与myBananavia 相同的类的实例

myBanana.getClass().isInstance(myApple)
Run Code Online (Sandbox Code Playgroud)