有没有办法从一个基类实例中找出派生类的名称?
例如:
class A{
....
}
class B extends A{
...
}
class c extends A{
...
}
现在如果一个方法返回一个A
对象,我能否找出它是否是类型B
或C
?
有没有办法从一个基类实例中找出派生类的名称?
例如:
class A{
....
}
class B extends A{
...
}
class c extends A{
...
}
现在如果一个方法返回一个A
对象,我能否找出它是否是类型B
或C
?
可以使用 instanceof
或 Class#getClass()
方法。
A returned = getA();
if (returned instanceof B) { .. }
else if (returned instanceof C) { .. }
getClass()
方法会返回以下其中之一:A.class
、B.class
、C.class
如果在if语句中,你需要进行向下转型 - 即:
((B) returned).doSomethingSpecificToB();
尽管如此,有时使用 instanceof 或
getClass()被认为是一种不良实践。您应该使用多态性来尝试避免检查具体子类的需要,但根据提供的信息,我无法告诉您更多。
A
的实现中拥有一个名为getType()
或类似的方法,并在B
和C
中覆盖该方法。由于Java中的所有方法都是虚拟的,对getType()
的调用将解析特定的子类型。 - aioobe您有尝试过使用 instanceof
吗?
例如:
Class A aDerived= something.getSomethingDerivedFromClassA();
if (aDerived instanceof B) {
} else if (aDerived instanceof C) {
}
//Use type-casting where necessary in the if-then statement.
回答你的问题:
有没有办法从基类对象中找出派生类的名称?
没有,超类无法告诉子类的名称/类型。
您必须询问对象(它是子类的实例)并询问它是否是特定子类的 instanceof
,或调用它的 getClass()
方法。
class A {
protected String classname;
public A() { this.classname = "A"; }
public String getClassname() { return this.classname; }
}
class B extends A {
public B() {
super();
this.classname = "B";
}
}
A a = new A();
a.getClassname(); // returns "A"
B b = new B();
b.getClassname(); // returns "B"
((A)b).getClassname(); // Also returns "B"
getClassname()
函数,但返回的是由构造函数设置的“B”构造函数的值。super();
。abstract class A {
public final String getName() {
return this.getClass().getName();
}
}
class B extends A { }
class C extends A { }
然后只需打印当前的class
名称:
B b = new B();
C c = new C();
System.out.println(b.getName());
System.out.println(c.getName());
输出:
com.test.B
com.test.C
不需要存储额外的字符串
,检查instanceof
或在任何子类中override
该方法。
我能想到两种方法: 1)使用Java反射API 2)另一种是使用instanceOf
另一种方法可以是将对象与对象进行比较,我不知道它可能是什么样子的,你可以试试这个。
if(x instanceof X xChild){
// use xChild
}
它既更短,也更少出错,因为它将测试变量(上面的示例中的x
)的运行时类型、向下转换和分配给新变量(上面的示例中的xChild
)的所有步骤结合在一起。阅读更多。
另一个例子:
public void addUIControl(UIControl control) {
if(control instanceof SelectList sl){
selectList = sl;
}
else if(control instanceof TextBox tb){
textBox = tb;
}
else if(control instanceof Button btn){
button = btn;
}
else {
throw new IllegalArgumentException("Uknown UIControl object has been passed to the SendFormMediator");
}
}