第四模块 反射以及java其他核心知识面试题
- 1. 什么是反射?
- 2.什么是 java 序列化?什么情况下需要序列化?
- 3. 动态代理是什么?有哪些应用?
- 4.怎么实现动态代理?
- 5.获取类对象的方式有哪些?
- 6.怎么获得类对象中成员
- 7.为什么要使用克隆?
- 8.如何实现对象克隆?
- 9.深度拷贝和浅度拷贝区别是什么?
- 10.说一下property文件?
- 11.枚举类和普通类的区别?
- 12.Java Stream操作流中的方法
- 13.javaUDP
- 14.XML读写
- 15.Java 时间类型
- 16.java 日期相关类
- 17.Calendar类(日历类)
1. 什么是反射?
根据类对象,可以动态获取类中的成员,属性,方法,构造器
2.什么是 java 序列化?什么情况下需要序列化?
序列化:将 Java 对象转换成字节流的过程。
a)当 Java 对象需要在网络上传输或者持久化存储到文件中时,就需要对 Java 对象进行序列化处理
b)当你想通过RMI传输对象的时候;
3. 动态代理是什么?有哪些应用?
动态生成一个新类,这个类包含原来类的所有功能,额外又添加新的功能,具有解耦意义,灵活,扩展性强。Spring的AOP,加事务,加权限,加日志
4.怎么实现动态代理?
首先必须定义一个接口,还要有一个InvocationHandler(将实现接口的类的对象传递给它)处理类。再有一个工具类Proxy(习惯性将其称为代理类,因为调用他的newInstance()可以产生代理对象,其实他只是一个产生代理对象的工具类)。利用到InvocationHandler,拼接代理类源码,将其编译生成代理类的二进制码,利用加载器加载,并将其实例化产生代理对象,最后返回。
5.获取类对象的方式有哪些?
类对象的获取方式
* 1.类名.class("全类名");
* 2.Class.forName(全类名);
* 2.ClassLoader.getSystemclassLoader();
* loadClass(全类名);
* 4.对象.getClass()
6.怎么获得类对象中成员
1.获取成员变量
getField():非私有的成员,可以得到父类非私有的所有成员变量
getDeclaredField():私有但不包括父类继承过程
2.获取构造器
getConstructor()
Constructor getDeclaredConstructor(String.class,int.class)
setAccessible(true);把私有的成员变为可访问
Object newInstance()
3.获取普通方法
getMethod("方法名",参数的类型)
getDeclaredMethod()
method.invoke(对象,传递的参数);
7.为什么要使用克隆?
想对一个对象进行处理,又想保留原有的数据进行接下来的操作,就需要克隆了,Java语言中克隆针对的是类的实例。
8.如何实现对象克隆?
有两种方式:
1). 实现Cloneable接口并重写Object类中的clone()方法;
2). 实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆
9.深度拷贝和浅度拷贝区别是什么?
基本数据类型:数据直接存储在栈中;引用数据类型:存储在栈中的是对象的引用地址,真实的对象数据存放在堆内存里。
浅拷贝:对于基础数据类型:直接复制数据值;对于引用数据类型:只是复制了对象的引用地址,新旧对象指向同一个内存地址,修改其中一个对象的值,另一个对象的值随之改变。
深拷贝:对于基础数据类型:直接复制数据值;对于引用数据类型:开辟新的内存空间,在新的内存空间里复制一个一模一样的对象,新老对象不共享内存,修改其中一个对象的值,不会影响另一个对象
深拷贝相比于浅拷贝速度较慢并且花销较大。
10.说一下property文件?
1.Properties文件
key=value形式存储数据
2.配置文件
1.文件流的形式读取文件 工程下
2.类加载器的方式 类名.class.getResourceAsStream()
3.读取Properties文件,java.util.Properties类支持读取
11.枚举类和普通类的区别?
1.普通类的对象是使用的时候使用new关键字创建
* 2.枚举类的对象自己在类中已经定义好的,只能使用这几个对象,不能自己创建
枚举类的注意点:
* 1.构造方法只能使用默认和private,枚举类型中的构造方法,仅限在本类中使用
* 2.成员的定义只能在常量之后
12.Java Stream操作流中的方法
Stream对象的获取(链式操作:减少代码的操作)
Collection:stream():串行流 单线程
parallelStream():并行流 多线程
of():存储数据
Arrays.stream():将数组转化为Stream对象
generate():产生数据
iterate():根据规则遍历数据
Stream limit():获取流中的多少个数据
skip():跳过流中的多少个数据
distinct():去重,把流中的重复数据去掉
filter():过滤,Predicate test()抽象方法 list.removeIf();
count():返回流中数据的个数
map(Function apply):映射 原本流中数据,根据映射规则得到新的数据流
sorted():排序new Comparator();
Stream:
boolean allMatch(Predicate);判断流中数据是否全部满足给定的条件
boolean anyMatch(Predicate): 判断流中数据是否满足给定的条件
boolean noneMatch(Predicate):判断流中数据是否全部不满足给定条件
Future get();Callable接口
Optional max:流中最大值
Optional min:流中最小值
get():获取存入的值
13.javaUDP
UDP:
* 数据包:
* DatagramSocket:
* DatagramPacket:
* send():发送数据包
* recevie():接受数据包
14.XML读写
XML读写:DOM4j(最常用) SAX(读一部分解析一部分) DOM(将文本的内容全部读到内存)
* 读:SAXReader
* read(): 返回值是document对象
* getRootElement():对象是Element
* element():指定节点,对象是element
* elements():全部子节点,返回对象是List
* attributes():返回对象是 Attribute
* getName():得到节点名
* getText():得到节点下的文本内容
* getName():得到Attribute的名
* getValue():得到Attribute的值
* 写:XMLWriter
* XMLWriter(文件输出流,OutputFormat.createPrittyPrint())
* write(document)
* documentHelper.createDocuement();
* add():对象是Element
15.Java 时间类型
Date Calendar SimpleDateFormat
* JDK1.8以后才有
* LocalDate:年月日
* LocalTime:时分秒
* LocalDateTime:年月日时分秒
时间分量的操作:
static now() 获取当前的系统时间
* static of:设置时间分量
* minusXXX:减少时间分量
* plusXXX:增加时间分量
日期与字符串之间的转换
DateTimeFormatter:
* parse():将字符串转日期
* format():将日期转字符串
16.java 日期相关类
在java.util.Date(常用)下和java.sql.Date下
创建对象:
Date():创建当前系统时间
Date(long l):给定毫秒值创建日期
getTime():获取对象日期的毫秒值
setTime(long l):根据给定的毫秒值设置日期
before:判断某个日期在日期之前
after:判断某个日期在日期之后SimpleDateFormat类:把日期和字符串进行转换
简单日期格式:java.text
format(Date类型):将日期转为字符串
parse(String类型):将字符串 转为日期
有个检查异常:ParseException,需要处理该异常,trycatch
日期格式:
yyyy:四位数的年
yy:两位数的年
MM:两位数的月
dd:两位数的天
hh:12小时制
HH:24小时制
mm:分
ss:秒
17.Calendar类(日历类)
日期时间分量的操作:
日历类,格里高利历(阳历)
abstract修饰的抽象类,该类不能直接创建对象
getInstance():工具方法(工厂方法),可以根据系统所在时区获取对象
get():获取时间分量
set():设置时间分量
add():增减时间分量
setTime(Date类型):根据给定日期设置日历
getTime():根据日历获取日期
获取时间分量最值
getActualMaximun():获取最大值
getActualMinimun():获取最小值
//set():设置时间分量
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH,Calendar.AUGUST);//设置为8月