在ArrayList的源码中看到这样的情形:
红框中的代码的作用就是判断实例类是否是某个指定类型。
elementData是Object[]的实例对象,而Object[]是系统定义的类。
看下面的代码:
public class Demo {
public static void main(String[] args) {
String str = new String("str");
System.out.println(str.getClass());
System.out.println(String.class);
System.out.println(str.getClass() == String.class);
}
}
/**
* 打印结果:
* class java.lang.String
* class java.lang.String
* true
*/
发现实例.getClass()和类.class的结果是相同的,都是获取的类型类。
其中getClass()是Object类中的一个方法,但没有实现,发现有一个native关键字,说明是通过C或C++实现的,非Java范畴,该方法返回该实例的类型。
类型类指的是代表一个类型的类,因为一切皆是对象,类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例。
每一个类型类,如String,Object或者自定义的Person类,都可以通过类.class获取到该类对应的类型类。
但需要注意的是,子类的类型类和父类的类型类是不同的,看下面的代码:
public class Demo {
public static void main(String[] args) {
// 注:String是Object的子类
Object obj = new String("str");
System.out.println(obj.getClass());
System.out.println(String.class);
System.out.println(Object.class);
System.out.println(obj.getClass() == String.class);
System.out.println(obj.getClass() == Object.class);
}
}
/**
* 打印结果:
* class java.lang.String
* class java.lang.String
* class java.lang.Object
* true
* false
*/
总结:
- 实例.getClass()和类.class都可以获取类型类。获取类型类后可以调用一些方法,如getName()获取该类型的全称。这两个在反射中用到比较多。
- getClass()是一个类的实例才具备的方法,而class是类所具备的。
- getClass()是在运行时才确定的,而class是在编译时就确定了。
在上面的源码中用来判断生成的实例是否是指定类型类。
说到这个,就想起了Java中的instanceof关键字也有这样的作用:一个类的实例是否属于另一个类。
public class Demo {
public static void main(String[] args) {
Parent parent = new Parent();
System.out.println("parent instanceof Parent: " + (parent instanceof Parent));
System.out.println("parent instanceof Child: " + (parent instanceof Child));
System.out.println("parent getClass Parent: " + (parent.getClass() == Parent.class));
System.out.println("parent getClass Child: " + (parent.getClass() == Child.class));
Parent child = new Child();
System.out.println("child instanceof Parent: " + (child instanceof Parent));
System.out.println("child instanceof Child: " + (child instanceof Child));
System.out.println("child getClass Parent: " + (child.getClass() == Parent.class));
System.out.println("child getClass Child: " + (child.getClass() == Child.class));
}
}
class Parent {
}
class Child extends Parent {
}
/**
* 打印结果:
* parent instanceof Parent: true
* parent instanceof Child: false
* parent getClass Parent: true
* parent getClass Child: false
*
* child instanceof Parent: true
* child instanceof Child: true
* child getClass Parent: false
* child getClass Child: true
*/
总结:
- instanceof也可以用来判断某个类的实例是否属于某个类。
- 注意,如果使用instanceof关键字,那么子类的实例也属于父类的范畴,即返回true,但getClass()则无法进行比较。
- 如果使用getClass()和class比较实例是否属于某个类,那么子类是子类,父类是子类,不会产生联系。
- 如果使用instanceof关键字比较实例是否属于某个类,那么子类实例从属于它的父类,但父类实例不会属于它的子类。