问题1:
对象有编译类型和运行类型
例如:
Object obj = new java.util.Date();
编译类型: Object
运行类型:java.util.Date();
需求:通过 obj 对象,调用 java.util.Date 类中的 toLocaleString 方法。obj.toLocaleString() 方法如果存在,编译成功,否则编译失败。
解决方案:因为 obj 的真实类型是 java.util.Date 类,所以我们可以把 obj 对象强制转换为 java.util.Date 类型。
java.util.Date date = (java.util.Date)obj;
date.toLocaleString();//调用成功
如果不知道 obj 的真实类型,就不能强转(底层有一个方法,返回一个 Object 类型的 java.util.Date 对象)
问题2:
在面向对象中,一切事物都可以看成是对象,那么问题来了,类这种事务是什么对象呢,又要使用什么类来表示类这种对象呢?
底层代码:
public static Object getObject(){
return new java.util.Date();
}
元数据(metadata):
描述数据的描述数据。
反射:
得到类的元数据的过程 –> 在运行时期,动态地去获取某一个类中的成员信息(构造器、方法、字段、内部类、接口、父类等等),并且把类的每一种成员,都描述成一个新的类。
Class:表示所有的类
Construction:表示所有的构造器
Method:表示所有的方法
Field:表示所有的字段
Class 类:用来描述类或者接口的类型,描述类的类
Class 类的实例:在 JVM 中的一份份字节码(.class),Class 实例表示在 JVM 中的类或者接口(枚举是一种特殊的类,注解是一种特殊的接口)。
当程序第一次使用某一个 java.util.Date 类的时候,就会把该类的字节码对象加载进 JVM,并创建出一个 Class 对象。
此时的 Class 对象就表示 java.util.Date 的字节码。
Class类可以表示N个类的是字节码对象,那么问题来了:到底怎么区分 Class 类,此时表示的又是哪一个类的字节码呢?
为了解决该问题,Class 类的设计者提供了泛型 –> Class
java.lang.String 类的字节码类型:Class
方式1:使用 class 属性
Class<java.util.Date> clz1 = java.util.Date.class;
方式2:通过对象的 getClass 方法来获取,getClass 是 Object 类中的方法
java.util.Date date = new java.util.Date();
Class<?> clz2 = date.getClass();
方式3:通过 Class 类中的静态方法 forName(String className)
Class<?> clz3 = class.forName("java.util.Date");
方式4:通过类加载器获取
ClassLoader classLoader = this.getClass().getClassLoader();
Class<?> clz4 = classLoader.loadClass("java.util.Date");
注意,同一类在 JVM 中只存在一份字节码对象,也就是上述claz1==clz2==clz3==clz4。
注:以后使用最多的是第三种,在框架中大量使用。
问题3:
在上述将了四种获取 Class 对象的方式,基本数据类型不能表示为对象,也就不能使用 getClass 的方式,基本数据类型没有类名的概念,也不能使用 Class.forName 的方式,如何表示基本类型的字节码对象呢?
所有的数据类型都有 class 属性:
Class clz = 数据类型.class;
九大内置 Class 实例:JVM中预先提供好的Class实例,分别为byte,short,int,long,float,double,boolean,char,void.
在八大基本数据类型的包装类中,都有一个常量:TYPE。用于返回该包装类对应基本类的字节码对象:
Integer.TYPE == int.class
System.out.println(Integer.class == int.class);//false
注意:Integer和int是不同的数据类型。
数组的 Class 实例:数组是引用数据类型 –> 数组其实就是对象
如何表示数组的 Class 实例:
方式1:数组类型.class;
方式2:数组对象.getClass();
注意:所有的具有相同维数和相同元素类型的数组共享同一份字节码对象,和元素没有关系。
附:
Class:描述所有类型,所以 Class 类中应该具有所有类型的相同方法。
Object:描述所有的对象,所以在 Object 类中应该具有所有对象的共同方法。