首页 > 编程知识 正文

java三大特性面试回答,java关于锁的面试题

时间:2023-05-05 10:44:27 阅读:152573 作者:3807

临近秋季招生,为暑假实习做准备,祝大家每天进步亿分! Day18本篇总结在代理设计模式中,日后会更新~

代理模型最直观的解释是通过代理成为代理对象“增强”! 也就是说,扩展被代理对象的功能(代理模型分为静态代理和动态代理。 动态代理的代理类是动态生成的,静态代理的代理类是预先写好的逻辑。 用Java实现动态代理的方式有: JDK动态代理CGLIB动态代理1、静态代理静态代理角色分析:

抽象角色:通常使用接口或抽象类实现。 真实角色:代理角色。 代理角色:代理实际角色,代理实际角色后,一般会做一些附属的操作。 调用者:使用代理角色执行一些操作。 以出租人的租赁住房为例,它涉及出租人、经纪人和房东。 (房东为被代理对象,中介为代理对象) ) ) )。

出租人通过中介的手段租赁房东的房子,代理对象的中介需要寻找出租人的租赁人,并从中获得中介费用。

代码实现

Rent.java是抽象的角色

//抽象角色:租赁publicinterfacerent { public void rent (; } Host.java是实际的角色

//实际角色:房东、房东出租房屋); }} Proxy.java是代理角色

//代理角色: publicclassproxyimplementsrent { privatehosthost; public Proxy () public proxy (host host ) ) { this.host=host; public void rent () ({ seeHouse )租赁; host.rent (; fare (; public void seeHouse () ({ System.out.println ) )“带着住客看房”); //收取中介费的public void fare () { System.out.println ) (“收取中介费”); }} Client.java的调用者,即客户

//客户班,普通客户去找特工! public class client (publicstaticvoidmain (string [ ] args ) )//房东租房子Host host=new Host ); //中介帮助房东ProxyProxy=NewProxy(Host ); //你去找经纪人! proxy.rent (; }静态代理的缺点:

您必须手动创建代理类。 随着需要代理的对象越来越多,代理类也越来越多。 为了解决这个问题,有动态代理!

2、动态智能体说到动态智能体,在面试时一定会听到动态智能体的两种实现方式。

首先,让我们看一下通用的UserService接口和UserServiceImpl实现类。

/* * @ author CSP * @ date 2021-06-03 */publicinterfaceuserservice {/* *登录*/void login (); /** *注销*/void logout (); }/* * * @ author CSP * @ date 2021-06-03 */publicclassuserviceimplimplementsuserservice { @ overridepublicvoidlogin () @Override public void logout (() { System.out.println ) )用户登录. ) ); }} JDK动态代理代码如下:

/* * @ author CSP * @ date 2021-06-03 */publicclassjdkproxyfactoryimplementsinvocationhandler (/目标对象(被委派对象this.target=target; } /** *创建委派对象* * @ return */publicobjectcreateproxy (() )/1 .获得目标

标对象的类加载器 ClassLoader classLoader = target.getClass().getClassLoader(); // 2.得到目标对象的实现接口 Class<?>[] interfaces = target.getClass().getInterfaces(); // 3.第三个参数需要一个实现invocationHandler接口的对象 Object newProxyInstance = Proxy.newProxyInstance(classLoader, interfaces, this); return newProxyInstance; } /** * 真正执行代理增强的方法 * * @param proxy 代理对象.一般不使用 * @param method 需要增强的方法 * @param args 方法中的参数 * @return */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("JDK 动态代理:登录/登出前逻辑校验......"); Object invoke = method.invoke(target, args); System.out.println("JDK 动态代理:登录/登出后日志打印......"); return invoke; } public static void main(String[] args) { // 1.创建对象 UserServiceImpl userService = new UserServiceImpl(); // 2.创建代理对象 JDKProxyFactory jdkProxyFactory = new JDKProxyFactory(userService); // 3.调用代理对象的增强方法,得到增强后的对象 UserService userServiceProxy = (UserService) jdkProxyFactory.createProxy(); userServiceProxy.login(); System.out.println("=================================="); userServiceProxy.logout(); }}

输出结果如下:

JDK 动态代理:登录/登出前逻辑校验......用户登录...JDK 动态代理:登录/登出后日志打印......==================================JDK 动态代理:登录/登出前逻辑校验......用户推出登录...JDK 动态代理:登录/登出后日志打印......
CGLIB 动态代理

代码如下:

/** * @author csp * @date 2021-06-03 */public class CglibProxyFactory implements MethodInterceptor { // 目标对象(被代理对象) private Object target; // 使用构造方法传递目标对象 public CglibProxyFactory(Object target) { super(); this.target = target; } /** * 创建代理对象 * * @return */ public Object createProxy() { // 1.创建Enhancer Enhancer enhancer = new Enhancer(); // 2.传递目标对象的class enhancer.setSuperclass(target.getClass()); // 3.设置回调操作 enhancer.setCallback(this); return enhancer.create(); } /** * 真正执行代理增强的方法 * @param o 代理对象 * @param method 要增强的方法 * @param objects 要增强方法的参数 * @param methodProxy 要增强的方法的代理 * @return * @throws Throwable */ @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("cglib 动态代理:登录/登出前逻辑校验......"); Object invoke = method.invoke(target, objects); System.out.println("cglib 动态代理:登录/登出后日志打印......"); return invoke; } public static void main(String[] args) { // 1.创建对象 UserServiceImpl userService = new UserServiceImpl(); // 2.创建代理对象 CglibProxyFactory cglibProxyFactory = new CglibProxyFactory(userService); // 3.调用代理对象的增强方法,得到增强后的对象 UserService userServiceProxy = (UserService) cglibProxyFactory.createProxy(); userServiceProxy.login(); System.out.println("=================================="); userServiceProxy.logout(); }}

测试结果如下:

cglib 动态代理:登录/登出前逻辑校验......用户登录...cglib 动态代理:登录/登出后日志打印......==================================cglib 动态代理:登录/登出前逻辑校验......用户推出登录...cglib 动态代理:登录/登出后日志打印...... 3、总结

面试题一:JDK动态代理和CGLIB动态代理区别?

① JDK 动态代理本质上是实现了被代理对象的接口,而 CGLib 本质上是继承了被代理对象,覆盖其中的方法。② JDK 动态代理只能对实现了接口的类生成代理,CGLib 则没有这个限制。但是 CGLib 因为使用继承实现,所以 CGLib 所以无法对 final 类、private 方法和 static方法进行代理。③ JDK 动态代理是 JDK 里自带的,CGLib 动态代理需要引入第三方的 jar 包。④ 在调用代理方法上,JDK动态代理是通过反射机制调用,CGLib 是通过 FastClass 机制直接调用。(看过一篇文章,介绍说 FastClass 简单的理解,就是使用一个 index 下标作为入参,可以直接定位到要调用的方法直接,并进行调用)

在性能上,JDK1.7 之前,由于使用了 FastClass 机制,CGLib 在执行效率上比 JDK 快,但是随着 JDK 动态代理的不断优化,从 JDK 1.7 开始,JDK 动态代理已经明显比 CGLib 更快了。

面试题一:JDK 动态代理为什么只能对实现了接口的类生成代理?

根本原因是通过 JDK 动态代理生成的类已经继承了 Proxy 类,所以无法再使用继承的方式去对类实现代理。

总结的面试题也挺费时间的,文章会不定时更新,有时候一天多更新几篇,如果帮助您复习巩固了知识点,还请三连支持一下,后续会亿点点的更新!

为了帮助更多拼搏的路灯从零进阶 Java 工程师,从CSDN官方那边搞来了一套 《Java 工程师学习成长知识图谱》,尺寸 870mm x 560mm,展开后有一张办公桌大小,也可以折叠成一本书的尺寸,有兴趣的小伙伴可以了解一下,当然,不管怎样博主的文章一直都是免费的~

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。