如果B
类和C
类扩展了A
类A
并且我有一个B
或C
类型的对象,那么如何确定它是实例的哪种类型?
#1楼
在这种情况下,我们可以使用反射
objectName.getClass().getName();
例:-
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getClass().getName();
}
在这种情况下,您将获得将对象传递给HttpServletRequest
接口引用变量的类的名称。
#2楼
提出了多个正确答案,但还有更多方法: Class.isAssignableFrom()
并仅尝试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) {
}
null
处理的差异
但是,在null
处理方面有所不同:
- 在前两个方法中,如果
obj
为null
(null
不是任何实例),则表达式的计算结果为false
。 - 第三种方法显然会抛出
NullPointerException
。 - 相反,第4和第5个方法接受
null
因为null
可以强制转换为任何类型!
要记住:
null
不是任何类型的实例,但是可以将其强制转换为任何类型。
笔记
- 如果对象不是
C
类型而是其子类,则不应使用Class.getName()
进行“ is-instance-of”测试,它可能具有完全不同的名称和包(因此,类名显然不匹配),但仍为C
类型。 - 由于相同的继承原因,
Class.isAssignableFrom()
不对称 :
如果obj
的类型是C
的子类,则obj.getClass().isAssignableFrom(C.class)
将返回false
。
#3楼
使用Object.getClass() 。 它返回对象的运行时类型。
#4楼
if (obj instanceof C) {
//your code
}
#5楼
您可以使用:
Object instance = new SomeClass();
instance.getClass().getName(); //will return the name (as String) (== "SomeClass")
instance.getClass(); //will return the SomeClass' Class object
HTH。 但是我认为在大多数情况下,将其用于控制流或类似的东西并不是一种好习惯。
#6楼
所建议使用的任何方法的任何使用均被视为基于不良OO设计的代码异味。
如果您的设计很好,则您不应该发现自己需要使用getClass()
或instanceof
。
任何建议的方法都可以使用,但是在设计方面要记住一些事情。
#7楼
“ Class
”类上还有一个.isInstance
方法。 如果您通过获取对象的类myBanana.getClass()
你可以看到,如果你的对象myApple
是同一类的实例myBanana
通过
myBanana.getClass().isInstance(myApple)
#8楼
如果您想在运行时知道,用isinstance()
检查还不够。 采用:
if(someObject.getClass().equals(C.class){
// do something
}