反射

1.对象有编译类型和运行类型

Object obj = new Date();

编译类型:Object       运行类型(obj对象的真实类型):Date

需求:根据对象obj调用Date类种的一个方法,toLocaleString,如何来做?
obj.toLcaleString()代码在编译阶段去编译类型Object中检查是否有该方法,若没有,编译失败。。

解决方案:

1:强制转换obj为Date类型(必须知道obj的真实类型)

2:在不知道obj的真实类型的情况下,就用反射。。

那什么是反射?反射是 得到元数据的行为。即Class是对一切类功能行为和状态的抽象

元数据:metadata 描述数据的描述数据


反射_第1张图片

Class类:用于描述一切类/接口。

Class实例:就是指JVM(虚拟机)中的一份字节码

对于对象来说,可以直接使用以下3种来获取Class实例

1)对象.getClass()

2)Class.forName(className[类的权限定名:包名+类名]);

3)数据类型.class


反射_第2张图片

但是我们的基本数据类型,就没有类的权限定名,也没有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对象)
注意:和数组中的元素没有一点关系。

反射_第3张图片

你可能感兴趣的:(反射)