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
ifobj
isnull
(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
becausenull
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 typeC
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 typeC
. - getname()不应该用于执行“is-instance-of”测试,因为如果对象不是C类型的,而是它的子类,那么它可能有一个完全不同的名称和包(因此类名显然不匹配),但它仍然是C类型的。
- For the same inheritance reason
Class.isAssignableFrom()
is not symmetric:obj.getClass().isAssignableFrom(C.class)
would returnfalse
if the type ofobj
is a subclass ofC
. - 出于相同的继承原因,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
ifobj
isnull
(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
becausenull
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 typeC
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 typeC
. - getname()不应该用于执行“is-instance-of”测试,因为如果对象不是C类型的,而是它的子类,那么它可能有一个完全不同的名称和包(因此类名显然不匹配),但它仍然是C类型的。
- For the same inheritance reason
Class.isAssignableFrom()
is not symmetric:obj.getClass().isAssignableFrom(C.class)
would returnfalse
if the type ofobj
is a subclass ofC
. - 出于相同的继承原因,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)