java Class 与反射
2021-08-27 14:49:48 0 举报
AI智能生成
登录查看完整内容
java Class 与反射
作者其他创作
大纲/内容
RTTI - 运行时类型识别 - Run-Time Type Identification
RTTI是什么?和反射是什么关系?RTTI是指一种思想:当有一个指向基础型别(父类)的reference(引用)时,RTTI机制让你找出其所指的确切型别。反射是RTTI的一种实现技术。RTTI的实现有2种, 分别是编译期确定 和 反射reflection机制(后期绑定)。
什么是后期绑定机制?java中的多态是怎么实现的?首先Java的所有方法绑定都采用“后期绑定”技术!!!要实现后期绑定机制, 那么java需要提供一些工具, 以便方法在运行时间正确判断对象类型,并调用适当的方法。这个工具就是“反射技术”。java多态就是隐式的(非程序员主动发起)使用了反射技术,在方法运行时, 判断方法的对象归属, 从而调用适当的方法。
RTTI
一个.class文件 对应一个Java类
Java类
.class文件被加载进JVM后,被JVM new出来的一个实例
Java对象
也属于一个java类,是一个泛型的类。Java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类(包括类和接口)的信息。Class类只存私有构造函数,因此对应Class对象只能有JVM创建和加载。
Class类
虚拟机会为每个.class文件创建一个Class对象, 里面保存的是基本信息, 用于实现RTTI运行时类型识别。
Class对象
这里首先做概念上的定义和区分:Java类Java对象Class类Class对象
首先 Class对象是由JVM自动加载的!!!
JVM加载Class对象的时机是?实际上所有的类都是在对其第一次使用时动态加载到JVM中的,当程序创建第一个对类的静态成员引用时,JVM就会加载这个被使用的类.
什么是类加载?把这个类的字节码文件, 转换为内存模型保存到JVM方法区中。
什么是类初始化?在类加载完成后, 在堆区创建描述这个类的java.lang.Class对象
上面说, 当程序第一次对类的静态成员引用时才会触发类加载,为什么在new 对象时,类加载也会被触发?new表达式简单理解创建对象并初始化!
所有Java对象都具备这个方法,该方法用于返回调用该方法的对象的所属类关联的Class对象List list = new ArrayList(); System.out.println(list.getClass().getName()); // java.util.ArrayList
可以通过这个方法了解一个对象的运行时类型
因为抽象类和接口不可能实例化对象,因此不能通过Object的getClass方法获得与抽象类和接口关联的Class对象
span style=\
使用类名加“.class”的方式即会返回与该类对应的Class对象.Class clazz = String.class; System.out.println(clazz.getName()); // java.lang.String
可以直接获得与指定类关联的Class对象,而并不需要有该类的对象存在。
首先了解类加载过程:加载:类加载过程的一个阶段:通过一个类的完全限定查找此类字节码文件,并利用字节码文件创建一个Class对象链接:验证字节码的安全性和完整性,准备阶段正式为静态域分配存储空间,注意此时只是分配静态成员变量的存储空间,不包含实例成员变量,如果必要的话,解析这个类创建的对其他类的所有引用。初始化:类加载最后阶段,若该类具有超类,则对其进行初始化,执行静态初始化器和静态初始化成员变量。
为什么使用字面常量的方式获取Class对象的引用不会触发类的初始化?我们获取字面常量的Class引用时,触发的应该是加载阶段。因为不涉及对象的创建,也不涉及到对静态成员的引用,只是获取类的相关信息,加载过程没到初始化阶段。
使用.class的方式 只是字面常量
该方法可以根据字符串参数所指定的类名获取与该类关联的Class对象。如果该类还没有被装入,该方法会将该类装入JVM。JVM装入被加载类后对其进行初始化,调用了其static块中的代码。
使用Class.forName方法
获取Class对象
获取Class对象引用的方式3种:通过继承自Object类的getClass方法Class类的静态方法forName字面常量的方式”.class”
初始化是类加载的最后一个阶段,也就是说完成这个阶段后类也就加载到内存中(Class对象在加载阶段已被创建),此时可以对类进行各种必要的操作了(如new对象,调用静态成员等),注意在这个阶段,才真正开始执行类中定义的Java程序代码或者字节码。
小总结
Class对象的加载及其获取方式
事实上instanceOf 与isInstance方法产生的结果是相同的
关于instanceof 关键字,它返回一个boolean类型的值,意在告诉我们对象是不是某个特定的类型实例。
isInstance方法则是Class类中的一个Native方法,也是用于判断对象类型的
instanceof 关键字与isInstance方法
getName() 一个Class对象描述了一个特定类的属性,Class类中最常用的方法getName以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。newInstance() Class还有一个有用的方法可以为类创建一个实例,这个方法叫做newInstance()。 例如:x.getClass.newInstance(),创建了一个同x一样类型的新实例。newInstance()方法调用默认构造器(无参数构造器)初始化新建对象。getClassLoader() 返回该类的类加载器。getComponentType() 返回表示数组组件类型的 Class。getSuperclass() 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。isArray() 判定此 Class 对象是否表示一个数组类。 虚拟机为每种类型管理一个独一无二的Class对象。因此可以使用==操作符来比较类对象。例如: if(e.getClass() == Employee.class)cast Animal animal= new Dog(); //下面两句等同于Dog dog = (Dog) animal; Class<Dog> dogType = Dog.class; Dog dog = dogType.cast(animal)
Class类的常用方法
深入理解Class对象
在运行时判断任意一个对象所属的类;
在运行时获取类的对象;
在运行时访问java对象的属性,方法,构造方法等。
反射的作用
Demo demo=new Demo();demo.getClass().getName()
通过一个对象获得完整的包名和类名
Class<?> demo = Class.forName(\"Reflect.Demo\");
实例化Class类对象
Person per = demo.newInstance();
通过Class实例化一个类的对象
Constructor<?> cons[]=demo.getConstructors();
取得一个类的构造函数
Class<?> intes[]=demo.getInterfaces();
返回一个类实现的接口
Class<?> temp=demo.getSuperclass();
取得一个类中的父类
Field[] field = demo.getDeclaredFields();
取得一个类的全部属性
Method method=demo.getMethod(\"sayChina\");method.invoke(demo.newInstance());
通过反射调用一个类中的方法
Field field = demo.getDeclaredField(\"sex\
通过反射操作属性
反射机制的示例
反射
java Class 与反射
0 条评论
回复 删除
下一页