1.对象有编译类型和运行类型
Object obj = new Date();
编译类型:Object 运行类型(obj对象的真实类型):Date
需求:根据对象obj调用Date类种的一个方法,toLocaleString,如何来做?
obj.toLcaleString()代码在编译阶段去编译类型Object中检查是否有该方法,若没有,编译失败。。
解决方案:
1:强制转换obj为Date类型(必须知道obj的真实类型)
2:在不知道obj的真实类型的情况下,就用反射。。
那什么是反射?反射是 得到元数据的行为。即Class是对一切类功能行为和状态的抽象
元数据:metadata 描述数据的描述数据
Class类:用于描述一切类/接口。
Class实例:就是指JVM(虚拟机)中的一份字节码
对于对象来说,可以直接使用以下3种来获取Class实例
1)对象.getClass()
2)Class.forName(className[类的权限定名:包名+类名]);
3)数据类型.class
但是我们的基本数据类型,就没有类的权限定名,也没有getClass方法。
问题:那么如何使用Class类来表示基本数据类型的Class实例?
byte,short,int,long,char,float,double,boolean 八大基本数据类型及 void 关键字
上述8种类型和void关键字,都有class属性
表示int 的Class对象:Class clz = int.class; 泛型为包装类Integer
表示Boolean的Class对象:Class clz =boolean.class
表示void的Class对象:Class clz = void.class;
说有的数据类型都有class属性,表示都是Class对象
思考:
int的包装类Integer
Integer.class ==? int.class
System.out.println(Integer.class == int.class) ==> false;
结果是false,说明是两份字节码。
Integer 和 int 是同一种 数据类型吗?
public void show(Integer i){}
public void show(int a){}
答案是: 不是;
但是在八大基本数据类型的包装类种都有一个头常量:TYPE.
TYPE表示的是该包装类对应的基本数据类型的class实例;
例:Integer.TYPE ==> int.class
System.out.println(Integer.TYPE == int.class) ==> true;
System.out.println(Integer.TYPE == Integer.class) ==> false;
数组的Class实例:
String[] sArr1 = {"A","C"};
String[] sArr2 = {};
String[][] sArr = {};
int[] iArr = {};
表示数组的Class实例:
String[] sArr1 = {"A","C"};
Class clz = String[].class;//此时clz表示的就是一个String类型的一维数组类型
所有具有相同元素类型和维数的数组才共享同一份字节码(Class对象)
注意:和数组中的元素没有一点关系。