赞
踩
Java面试总纲(持续更新!) | https://libusi.blog.csdn.net/article/details/104268324 |
目录
@、什么是 java 序列化?Java序列化与反序列化,什么情况下需要序列化?
@、动态代理是什么?有哪些应用?怎么实现动态代理?有哪些应用?
其实就是动态加载一个指定的类,并获取该类中的所有的内容。而且将字节码文件封装成对象,并将字节码文件中的内容都封装成对象,这样便于操作这些成员。简单说:反射技术可以对一个类进行解剖。
反射就是把java类中的各种成分映射成一个个的Java对象
例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分 映射成一个个对象。
反射的好处:大大的增强了程序的扩展性。
反射的基本步骤:
1、获得Class对象,就是获取到指定的名称的字节码文件对象。
2、实例化对象,获得类的属性、方法或构造函数。
3、访问属性、调用方法、调用构造函数创建对象。
可以节省很多资源,动态加载
我们的项目底层有时是用mysql,有时用oracle,需要动态地根据实际情况加载驱动类,
这个时候反射就有用了,
假设 com.java.dbtest.myqlConnection,com.java.dbtest.oracleConnection这两个类我们要用,
这时候我们的程序就写得比较动态化,通过Class tc =Class.forName("com.java.dbtest.TestConnection");
通过类的全类名让jvm在服务器中找到并加载这个类,而如果是oracle则传入的参数就变成另一个了。
这时候就可以看到反射的好处了,这个动态性就体现出java的特性了!
Java中使用反射获取一个类的全部信息
- public static void getFunctionAllMessages(String className) throws ClassNotFoundException, InstantiationException,
- IllegalAccessException, IllegalArgumentException, InvocationTargetException {
-
- // className为类的全名
- Class c = Class.forName(className);
- // 获取类名
- System.out.println("类名:" + c.getSimpleName());
- // 获取父类名
- System.out.println("父类名:" + c.getSuperclass().getSimpleName());
- // 获取这个类的全部方法
- Method[] methods = c.getMethods();
- System.out.println("方法有:");
- for (int i = 0; i < methods.length; i++) {
- // 打印这个方法的修饰符 返回类型 方法名
- System.out.println(Modifier.toString(methods[i].getModifiers()) + " " + methods[i].getReturnType().getName()
- + " " + methods[i].getName() + "();");
-
- // 反射调用特定方法
- // if(methods[i].getName().equals("isEmpty")) {
- // Object ob = c.newInstance();
- // System.out.println("===="+methods[i]);
- // System.out.println(methods[i].invoke(ob));
- // }
- }
-
- System.out.println("属性有:");
- // 获取这个类的全部属性
- Field[] fields = c.getDeclaredFields();
-
- for (int i = 0; i < fields.length; i++) {
- // 打印属性的 修饰符 类型 名称
- System.out.println(Modifier.toString(fields[i].getModifiers()) + " " + fields[i].getGenericType() + " "
- + fields[i].getName());
- }

//类加载
Class clazz = Class.forName("cn.itcast.bean.Person");
// 直接获得指定的类型
clazz = Person.class;
// 根据对象获得类型
Object obj = new Person("zhangsan", 19);
clazz = obj.getClass();
Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。
为什么需要序列化与反序列化
我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要Java序列化与反序列化了。换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。
当我们明晰了为什么需要Java序列化和反序列化后,我们很自然地会想Java序列化的好处。其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。
Object obj = clazz.newInstance();//该实例化对象的方法调用就是指定类中的空参数构造函数,给创建对象进行初始化。
当指定类中没有空参数构造函数时,该如何创建该类对象呢?请看method_2();
public static void method_2() throws Exception {
Class clazz = Class.forName("cn.itcast.bean.Person");
//既然类中没有空参数的构造函数,那么只有获取指定参数的构造函数,用该函数来进行实例化。
//获取一个带参数的构造器。
Constructor constructor = clazz.getConstructor(String.class,int.class);
//想要对对象进行初始化,使用构造器的方法newInstance();
Object obj = constructor.newInstance("zhagnsan",30);
//获取所有构造器。
Constructor[] constructors = clazz.getConstructors();//只包含公共的
constructors = clazz.getDeclaredConstructors();//包含私有的
for(Constructor con : constructors) {
System.out.println(con);
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。