如何确定对象的类?

时间:2022-10-10 16:45:24

If class B and class C extend class A and I have an object of type B or C, how can I determine of which type it is an instance?

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

7 个解决方案

#1


688  

if (obj instanceof C) {
//your code
}

#2


285  

Use Object.getClass(). It returns the runtime type of the object.

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

#3


135  

Multiple right answers were presented, but there are still more methods: Class.isAssignableFrom() and simply attempting to cast the object (which might throw a ClassCastException).

给出了多个正确的答案,但是仍然有更多的方法:Class.isAssignableFrom()和简单地尝试转换对象(这可能抛出ClassCastException)。

Possible ways summarized

Let's summarize the possible ways to test if an object obj is an instance of type C:

让我们总结一下测试对象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) {
}

Differences in null handling

There is a difference in null handling though:

但是零处理有一个区别:

  • In the first 2 methods expressions evaluate to false if obj is null (null is not instance of anything).
  • 在前两种方法中,如果obj为null (null并不是任何实例),表达式就会被计算为false。
  • The 3rd method would throw a NullPointerException obviously.
  • 第三种方法显然会抛出NullPointerException。
  • The 4th and 5th methods on the contrary accept null because null can be cast to any type!
  • 相反,第4和第5个方法接受null,因为null可以被转换成任何类型!

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

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

Notes

  • Class.getName() should not be used to perform an "is-instance-of" test becase if the object is not of type C but a subclass of it, it may have a completely different name and package (therefore class names will obviously not match) but it is still of type C.
  • getname()不应该用于执行“is-instance-of”测试,因为如果对象不是C类型的,而是它的子类,那么它可能有一个完全不同的名称和包(因此类名显然不匹配),但它仍然是C类型的。
  • For the same inheritance reason Class.isAssignableFrom() is not symmetric:
    obj.getClass().isAssignableFrom(C.class) would return false if the type of obj is a subclass of C.
  • 出于相同的继承原因,Class.isAssignableFrom()并不对称:如果obj的类型是C的子类,object . getclass (). isassignablefrom (C.class)将返回false。

#4


30  

You can use:

您可以使用:

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

HTH. But I think most of the time it is no good practice to use that for control flow or something similar...

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

#5


25  

Any use of any of the methods suggested is considered a code smell which is based in a bad OO design.

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

If your design is good, you should not find yourself needing to use getClass() or instanceof.

如果您的设计很好,那么您不应该发现自己需要使用getClass()或instanceof。

Any of the suggested methods will do, but just something to keep in mind, design-wise.

任何建议的方法都可以,但只是在设计方面要记住的东西。

#6


14  

We can use reflection in this case

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

objectName.getClass().getName();

Example:-

例子:-

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

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

In this case you will get name of the class which object pass to HttpServletRequest interface refference variable.

在本例中,您将获得传递给HttpServletRequest接口refference变量的类的名称。

#7


13  

There is also an .isInstance method on the "Class" class. if you get an object's class via myBanana.getClass() you can see if your object myApple is an instance of the same class as myBanana via

“类”上还有一个. isinstance方法。如果您通过mybanna . getclass()获得一个对象的类,您可以看到您的对象myApple是否是与myBanana via相同的类的实例

myBanana.getClass().isInstance(myApple)

#1


688  

if (obj instanceof C) {
//your code
}

#2


285  

Use Object.getClass(). It returns the runtime type of the object.

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

#3


135  

Multiple right answers were presented, but there are still more methods: Class.isAssignableFrom() and simply attempting to cast the object (which might throw a ClassCastException).

给出了多个正确的答案,但是仍然有更多的方法:Class.isAssignableFrom()和简单地尝试转换对象(这可能抛出ClassCastException)。

Possible ways summarized

Let's summarize the possible ways to test if an object obj is an instance of type C:

让我们总结一下测试对象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) {
}

Differences in null handling

There is a difference in null handling though:

但是零处理有一个区别:

  • In the first 2 methods expressions evaluate to false if obj is null (null is not instance of anything).
  • 在前两种方法中,如果obj为null (null并不是任何实例),表达式就会被计算为false。
  • The 3rd method would throw a NullPointerException obviously.
  • 第三种方法显然会抛出NullPointerException。
  • The 4th and 5th methods on the contrary accept null because null can be cast to any type!
  • 相反,第4和第5个方法接受null,因为null可以被转换成任何类型!

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

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

Notes

  • Class.getName() should not be used to perform an "is-instance-of" test becase if the object is not of type C but a subclass of it, it may have a completely different name and package (therefore class names will obviously not match) but it is still of type C.
  • getname()不应该用于执行“is-instance-of”测试,因为如果对象不是C类型的,而是它的子类,那么它可能有一个完全不同的名称和包(因此类名显然不匹配),但它仍然是C类型的。
  • For the same inheritance reason Class.isAssignableFrom() is not symmetric:
    obj.getClass().isAssignableFrom(C.class) would return false if the type of obj is a subclass of C.
  • 出于相同的继承原因,Class.isAssignableFrom()并不对称:如果obj的类型是C的子类,object . getclass (). isassignablefrom (C.class)将返回false。

#4


30  

You can use:

您可以使用:

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

HTH. But I think most of the time it is no good practice to use that for control flow or something similar...

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

#5


25  

Any use of any of the methods suggested is considered a code smell which is based in a bad OO design.

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

If your design is good, you should not find yourself needing to use getClass() or instanceof.

如果您的设计很好,那么您不应该发现自己需要使用getClass()或instanceof。

Any of the suggested methods will do, but just something to keep in mind, design-wise.

任何建议的方法都可以,但只是在设计方面要记住的东西。

#6


14  

We can use reflection in this case

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

objectName.getClass().getName();

Example:-

例子:-

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

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

In this case you will get name of the class which object pass to HttpServletRequest interface refference variable.

在本例中,您将获得传递给HttpServletRequest接口refference变量的类的名称。

#7


13  

There is also an .isInstance method on the "Class" class. if you get an object's class via myBanana.getClass() you can see if your object myApple is an instance of the same class as myBanana via

“类”上还有一个. isinstance方法。如果您通过mybanna . getclass()获得一个对象的类,您可以看到您的对象myApple是否是与myBanana via相同的类的实例

myBanana.getClass().isInstance(myApple)