关于java:如何确定对象的类?

How to determine an object's class?

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


1
2
3
if (obj instanceof C) {
//your code
}


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


提出了多种正确的答案,但仍有更多的方法:Class.isAssignableFrom()和简单地尝试投射物体(可能会抛出ClassCastException)。

总结可能的方法

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 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) {
}

null处理差异

不过,null处理方式不同:

  • 在前2种方法中,如果objnull(null不是任何事物的实例),则表达式对false进行评估。
  • 第三种方法显然会抛出一个NullPointerException
  • 相反,第4和第5种方法接受null,因为null可以强制转换为任何类型!

To remember: null is not an instance of any type but it can be cast to any type.

号笔记

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


您可以使用:

1
2
3
Object instance = new SomeClass();
instance.getClass().getName(); //will return the name (as String) (=="SomeClass")
instance.getClass(); //will return the SomeClass' Class object

Hth.但我认为在大多数情况下,将其用于控制流程或类似的事情并不是一个好的实践。


使用任何建议的方法都被认为是基于糟糕的OO设计的代码味道。

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

任何建议的方法都可以,但只是记住一些设计方面的问题。


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

1
objectName.getClass().getName();

示例:

1
2
3
4
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    String name = request.getClass().getName();
}

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


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

1
myBanana.getClass().isInstance(myApple)