背景说明
- 今天,在对在子类中调用getClass().getName()以及调用super.getClass().getName()的结果有点迷惑(获取的都是子类的字符串名称)
-
调用方式
getClass().getName():直接在子类中调用
- super.getClass().getName():直接在子类中调用
- super.getDogClassName():调用父类中的方法,父类中该方法使用了
getClass().getName()
- getClass().getSuperclass().getName():调用Class类中的getSuperclass()来获取父类名称
示例代码
/**
* 定义超类Dog
*/
class Dog {
public String getDogClassName() {
return getClass().getName();
}
}
/**
* 定义子类SmallDog
*/
class SmallDog extends Dog {
public String getClassName() {
return getClass().getName();
}
public String getSuperClassName() {
return super.getClass().getName();
}
public String getSuperDogClassName() {
return super.getDogClassName();
}
public String getClassSuperName() {
return getClass().getSuperclass().getName();
}
}
public class Test {
public static void main(String[] args) {
SmallDog dog = new SmallDog();
// 打印:SmallDog
System.out.println(dog.getClassName());
// 打印:SmallDog
System.out.println(dog.getSuperClassName());
// 打印:SmallDog
System.out.println(dog.getSuperDogClassName());
// 打印:Dog
System.out.println(dog.getClassSuperName());
}
}
场景结果
- 1)当子类中直接调用getClass().getName()时:
- 获取的是子类名称字符串SmallDog
- 2)当子类中直接调用super.getClass().getName()时:
- 获取的仍然是子类名称字符串SmallDog
- 3)当子类调用父类中的方法super.getDogClassName()时:
- 获取的还是子类名称字符串SmallDog
4)当子类中调用getClass().getSuperclass().getName()时:
getClass()方法归根结底,是所有类的超类Object定义的
public final native Class<?> getClass();
- 这个方法一开始就被定义为final方法,任何子类都不可以将其覆盖
- 从继承关系上来看,子类getClass方法继承关系为:子类继承于父类,父类继承于父类的父类,以此类推,最终继承于Object类
- 可知,子类中的getClass方法来自于Object类
- 另外,因为此方法来源于 继承 ,而子类继承父类可以理解为:子类拷贝了一份父类的域或方法 (但不可见) 【注意,只是辅助理解,不代表底层具体实现方式】
- 那么,在子类中使用 super 关键字来调用父类中的方法便可以理解为:调用从父类中拷贝的方法,其本质上还是调用子类内部方法
- 因此,场景1、2、3的结果都是一样的,都等价于在子类中直接调用getClass().getName()方法,结果一致
又如何正确地获取父类名称字符串呢
- 在getClass()获取到Class类后,直接调用getSuperclass().getName()方法即可:
getClass().getSuperclass().getName()