Loading

Java面试题4 反射 动态代理

自己尝试通过打字来回答一些网上常见的面试题,答案仅代表我自己的观点

57. 什么是反射?

除了基本类型,Java中的任何东西都是对象,但我们始终没办法用对象表示方法属性这些概念。反射的作用就是给我们提供一些API来表示这些东西。

有了反射,我们能做的就多了,比如根据类名来找到代表一个类的Class对象、通过Class对象创建该类的实例、获取一个类中的所有属性、获取一个类中的所有方法、获取类、属性、方法上的所有注解等。

我们可以说整个JavaEE开发都是基于反射的,Json、ORM框架使用反射将各种数据与Java对象互相转换,Spring框架使用反射提供依赖注入、注解解析,很多场景下需要依赖的动态代理技术也处处都使用反射来实现。

58. 什么是 java 序列化?什么情况下需要序列化?

序列化是将Java中的对象以某种方式持久化。

当你需要在当前程序之外传递对象时就需要把对象序列化,当对象传递到目的地时,对方会对对象数据进行反序列化,得到原来的对象。常见于通过网络传输对象数据时,比如RMI。

59. 动态代理是什么?有哪些应用?

说到动态代理就要说代理模式。

代理模式是一个对象A持有另一个对象对象B的实例,当调用对象A时,对象A会委托对象B来执行,同时,A可以在执行前后做一些操作,比如记录日志、打开事务关闭事务等。代理模式的优点是,调用者并不知道对象对象A是一个代理,它就把A当成B用,而A所做的额外操作对于调用者来说是透明的;代理模式的缺点就是比较难写,因为它要把对象B所具有的所有功能在对象A中提供,并在A中调用B,而且当需要代理的对象多起来,每一个对象你都得手动编写一个代理。

动态代理就是在运行时根据需求动态生成这些代理类,它具有静态代理的所有优点并且它便于创建、灵活性强。

动态代理的应用,最常见的就是实现AOP、典型的应用场景还有事务、日志、权限校验。

60. 怎么实现动态代理?

不同的动态代理工具实现起来的方式不同,不过有几个组件是一般的动态代理工具中都会提供的:

  1. 被代理类——你希望扩展功能的类
  2. 代理类——代理类不需要你来编写,是自动生成的,是发布给调用者的实际对象,这里面包含了你想扩展的功能
  3. 调用拦截——这里是当你的代理类中的方法被调用时,你应该做什么,是否调用被代理类的对应方法?是否拦截异常?发生异常怎么办?委托前后应该做什么?

同时,动态代理工具一般都会自动生成一个Java类的字节码、这个类就是代理类,然后会用ClassLoader来加载这个类到JVM中。

有些动态代理要求被代理类必须实现接口,比如JDK的动态代理,有些没这些限制,比如Cglib。

61. 为什么要使用克隆?

克隆一般发生在你要发布一个对象的副本给外部时。如果你直接发布这个对象本身,当这个对象并非不可变对象时,外部对该对象的修改会反应给你,你不希望这种行为发生,所以你要克隆该对象的副本然后发布副本。

62. 如何实现对象克隆?

Java里好像有个Cloneable接口吧,这个接口有个clone方法,实现这个方法,并在这个方法中返回一个当前对象的副本。

还有一种不那么优雅的方式,和JS中比较常用的JSON.parse(JSON.stringify())深克隆方式类似,原理就是将对象序列化成某种形式,可以是Java的序列化、Json、XML、甚至是存到数据库中,然后再把序列化后的该对象反序列化,得到一个新的对象。这种方式可能性能不是那么好、但是比较省心。另外一个缺点是你没法指定克隆的深度,只能是深克隆。

63. 深拷贝和浅拷贝区别是什么?

深拷贝递归拷贝所有子对象,造成的结果就是不管子对象的深度多深,对它的修改都不会影响到源对象。浅拷贝通常来说并不拷贝子对象,但是我个人认为这个拷贝深度可以被灵活的指定,只要不是完全递归拷贝所有子对象那么都可以称作浅拷贝。

posted @ 2022-06-23 09:27  yudoge  阅读(262)  评论(0编辑  收藏  举报