在 Java 中使用 Object.getClass() 是不好的做法吗?
Is it bad practice to use Object.getClass() in Java?
我很清楚 反射 只能作为最后的手段使用,即使你处于似乎应该依赖它的情况下暗示你的设计不好。这是一个非常强大的工具,使用时应格外小心。
我也知道 Java 存储一些关于对象的内部管理信息,所以理论上它应该是一个相对使用 Object.getClass()
确定对象的动态类型的廉价操作(至少与没有此类管理数据的语言相比便宜,例如 C++,其中 RTTI 需要昂贵的 vtable 查找)。
真的是这样吗? 不好 在Java 中检查某个对象是否t 是某个派生的类型使用getClass()
?
检查对象的类型并不是坏习惯。但是,Java 中的反射仍然被认为是一项昂贵的操作。
与其使用 getClass()
来确定类型,更好的做法是使用 instanceof
来检查类型是否与您正在寻找的相匹配。
例如:
if(theObject instanceof SomeBaseClassObject){
//do something
}
当您尝试根据类型选择行为时,检查对象的运行时类型被认为是一种不好的做法:
if (animal instanceof Cat) { // or animal.getClass() == Cat.class
((Cat) animal).meow();
} else if (animal instanceof Dog) {
((Dog) animal).woof();
}
如果你这样做,你会忽略多态性,因为它告诉你这样做:
animal.makeSound();
但是在很多情况下,您需要知道对象类型并使用 .getClass()
和 instanceof
- 在使用反射、使用第三方库等时。如果您不破解多态性,你没问题。
我会说这完全取决于具体情况,但我见过的大多数情况都是不好的做法。因为它通常被用来替代适当的设计。
使用 getClass
的不良做法示例如下:
public void method(SomeObject obj) {
if(obj.getClass() == A.class) {
// do something for A
}
if(obj.getClass() == B.class) {
// do something for B
}
...
}
为什么不委托给 obj
:
obj.doSomething();
或者通过重载方法拆分案例:
public void method(A obj){...}
public void method(B obj){...}
关键是,很多时候它是可以避免的,这通常表明您在运行时工作,而可以在编译时完成。
我很清楚 反射 只能作为最后的手段使用,即使你处于似乎应该依赖它的情况下暗示你的设计不好。这是一个非常强大的工具,使用时应格外小心。
我也知道 Java 存储一些关于对象的内部管理信息,所以理论上它应该是一个相对使用 Object.getClass()
确定对象的动态类型的廉价操作(至少与没有此类管理数据的语言相比便宜,例如 C++,其中 RTTI 需要昂贵的 vtable 查找)。
真的是这样吗? 不好 在Java 中检查某个对象是否t 是某个派生的类型使用getClass()
?
检查对象的类型并不是坏习惯。但是,Java 中的反射仍然被认为是一项昂贵的操作。
与其使用 getClass()
来确定类型,更好的做法是使用 instanceof
来检查类型是否与您正在寻找的相匹配。
例如:
if(theObject instanceof SomeBaseClassObject){
//do something
}
当您尝试根据类型选择行为时,检查对象的运行时类型被认为是一种不好的做法:
if (animal instanceof Cat) { // or animal.getClass() == Cat.class
((Cat) animal).meow();
} else if (animal instanceof Dog) {
((Dog) animal).woof();
}
如果你这样做,你会忽略多态性,因为它告诉你这样做:
animal.makeSound();
但是在很多情况下,您需要知道对象类型并使用 .getClass()
和 instanceof
- 在使用反射、使用第三方库等时。如果您不破解多态性,你没问题。
我会说这完全取决于具体情况,但我见过的大多数情况都是不好的做法。因为它通常被用来替代适当的设计。
使用 getClass
的不良做法示例如下:
public void method(SomeObject obj) {
if(obj.getClass() == A.class) {
// do something for A
}
if(obj.getClass() == B.class) {
// do something for B
}
...
}
为什么不委托给 obj
:
obj.doSomething();
或者通过重载方法拆分案例:
public void method(A obj){...}
public void method(B obj){...}
关键是,很多时候它是可以避免的,这通常表明您在运行时工作,而可以在编译时完成。