目录
1.反射与封装性是否矛盾
不矛盾;虽然通过反射能够调用私有的属性、方法、构造器,封装性的目的是不让别人去调用这些私有结构,使用反射时完全可以不调用它们,相反需要调用的结构都已经public过了,因此不矛盾
2.反射创建对象的原理
1.Java中的反射:动态获取运行时类的全部信息和动态调用对象方法的功能称为反射机制
2.反射需要调用newInstance()方法创建运行时类对象,而使用newInstance()方法创建对象时需要调用运行时类的无参构造器,并且该无参构造器必须声明为public;
3.归根结底,只有构造器才能创建对象;反射也是调用public声明的无参构造器创建运行时类的对象
3.反射的实现方式
1.通过运行时类的属性:类名.class
2.通过运行时类的对象:对象名.getClass()
3.通过Class的静态方法:Class.forName("类的路径");
4.通过类的加载器:classLoader
4.反射的优缺点
优点:能够动态获取运行时类的实例,提高灵活性
缺点:反射的性能较低,需要解析字节码文件,并解析内存中的对象
5.Java反射API
1.Class类:反射的核心类,获取类的属性、方法等信息
2.Field类:java.lang.reflect包中的类,表示类的成员变量,能够获取和设置类的属性值
获取属性结构:
getFields():获取当前运行时类及其父类中声明为public访问权限的属性
getDeclaredFields():获取当前运行时类中声明的所有属性(不包含父类中声明的属性)
3.Method类:java.lang.reflect包中的类,表示类的方法,能够获取类的方法信息或执行方法
获取方法:
getMethods(): 获取当前运行时类及其父类中声明为public访问权限的方法
getDeclaredMethods(): 获取当前运行时类中声明的所有方法(不包含父类中声明的方法)
4.Constructor类:java.lang.reflect包中的类,表示类的构造方法
获取构造器:
getConstructors
getDeclaredConstructors
Class clazz = Class.forName("com.gz.pojo.User");
Field[] fields = clazz.getFields();
Method[] methods = clazz.getMethods();
Constructor[] constructors = clazz.getConstructors();
6.java的序列化机制
允许将内存中的Java对象转换为和平台无关的二进制流,从而允许将这种二进制流持久的保存在磁盘上,或通过网络将二进制流传输到另一个网络节点。当其他程序获取了这种二进制流后,可以将其转换为原来的Java对象。
7.Java的序列化与反序列化
使用对象流:ObjectInputStream;ObjectOutputStream
ObjectInputStream:反序列化:将磁盘文件中的对象还原为一个内存中Java对象
ObjectOutputStream:序列化:将一个Java对象保存到磁盘或者通过网络传输出去
8.如何实现序列化
若想实现序列化,需要满足两个要求
1.当前类需要实现接口:Serializable;且当前类需要提供一个全局常量:SerialVersionUID
2.必须保证当前类的内部所有属性是可序列化的(因为对象流无法序列化static和transient修饰的成员变量)
9.为什么需要序列化
Java平台中,可以在内存中创建可复用的Java对象,但一般情况下,只有当JVM运行过程中,这些对象才能够存在。在现实应用中,可能需要在JVM没有运行的情况下保存指定的Java对象,并且可以在需要时重新读取,这就需要用到Java的序列化机制。
10.序列化对象的保存
使用Java对象序列化后,保存的对象会以字节的形式保存。在需要时,将这些字节组装为对象。(记住,无法序列化static和transient修饰的成员变量)