0 1

jdk 动态代理的问题0

我在研究jdk 动态代理发现一个问题:

public class PeoxyObject implements InvocationHandler
自定义的
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {

System.out.println(" proxy_    "+ proxy);
                ......
        }
.....
}

/*
发现 一句 System.out.println(" proxy_    "+ proxy); 引起 :
* Exception in thread "main" java.lang.StackOverflowError
at java.lang.String.getChars(String.java:863)
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:416)
at java.lang.StringBuilder.append(StringBuilder.java:132)
at java.lang.StringBuilder.<init>(StringBuilder.java:110)
at $Proxy0.toString(Unknown Source)



*/

不至于吧,proxy都不能引用吗??


请问各位大虾,什么原因呢?WHY


问题补充:其实Proxy已经有写明:
An invocation of the hashCode, equals, or toString methods declared in java.lang.Object on a proxy instance will be encoded and dispatched to the invocation handler's invoke method in the same manner as interface method invocations are encoded and dispatched, as described above. The declaring class of the Method object passed to invoke will be java.lang.Object. Other public methods of a proxy instance inherited from java.lang.Object are not overridden by a proxy class, so invocations of those methods behave like they do for instances of java.lang.Object.


虽然如此,而且看了一下Proxy的源码,仍然不是很明白...
2013年9月04日 13:57

7个答案 按时间排序 按投票排序

0 0

jdk的动态代理默认会对object的toString()方法进行代理,你这样system.out会造成无限递归

2013年9月05日 10:00
0 0

你在这里打印代理 就是调用代理toString()方法
  1.然后进入invoke中执行 执行了真实对象的tostring() 然后又打印 死循环
 

2013年9月04日 18:05
0 0

2013年9月04日 15:43
0 0

2013年9月04日 15:42
0 0

每次调用proxy.toString()时,debug显示
【$Proxy0.toString() line: not available [local variables unavailable]】
然后就会再次调用invoke()方法。

依次类推,形成了一个无限递归。

2013年9月04日 14:40
0 0

试了下确实如此,很有意思的问题,一起探讨一下。

只要调用了proxy.toString()就会发生这个java.lang.StackOverflowError的问题。
而java.lang.StackOverflowError是递归太深的时候导致的堆栈溢出问题。
我在System.out.println(proxy)前面加了个System.out.println(count++),其中count是静态的数字型变量(初始为1),发现以下现象:
1、没有proxy.toString()的情况下,只调用了一次invoke()方法,所以向控制台打印了1
2、有proxy.toString()的情况下,会无限次调用invoke()方法,直到发生StackOverflowError,所以控制台打印了1、2、3、4、到很大的数字
看上去可能是:调用proxy.toString()的情况下,会发生递归调用invoke()方法的现象,从而无限递归,直到发生StackOverflowError。

原因不明,等大神现身回复。

2013年9月04日 14:33
0 0

java.lang.StackOverflowError 这个错误一般是死循环的迭代调用报出来的。

引用

InvocationHandler is the interface implemented by the invocation handler of a proxy instance.
Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.

从描述中可以看到,你的例子中每次进入invoke方法区,会调用proxy的方法,造成去迭代调用invoke方法。

2013年9月04日 14:19

相关推荐

    JDK动态代理_JDK动态代理

    ### JDK动态代理详解 #### 一、引言 在软件工程中,代理模式是一种常见的设计模式,它通过为一个对象提供一个替代品或占位符来控制对这个对象的访问。这种模式通常用于添加额外的功能(例如日志记录、事务管理等)...

    浅谈JDK动态代理与CGLIB代理去区别

    本篇文章将深入探讨JDK动态代理和CGLIB代理的区别,以及它们在实际应用中的选择。 首先,JDK动态代理主要依赖于java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。Proxy类用于创建一个代理对象...

    关于jdk动态代理的源码剖析

    通过上述分析,我们可以看出JDK动态代理是一种非常强大且灵活的技术,它不仅可以帮助我们解决实际开发中遇到的问题,还能够提高代码的可维护性和可扩展性。理解其工作原理对于深入学习Java编程有着重要意义。

    Spring框架中JDK动态代理和cglib动态代理

    Spring 框架中 JDK 动态代理和 CGLIB 动态代理是 Spring AOP 中一个非常重要的知识点。Spring AOP 框架会根据实际情况选择使用 JDK 的动态代理还是 CGLIB 的动态代理。 JDK 动态代理是 Java 自带的动态代理机制,它...

    jdk动态代理技术详解

    JDK 动态代理技术详解 JDK 动态代理技术是 Java 语言自身对动态代理的支持,类似于 JDK 中在 java.util 包中提供 Observable 类和 Observer 接口提供对观察者模式的语言级支持。动态代理的优点是可以动态地为软件...

    JDK动态代理源码

    在Java编程领域,JDK动态代理是一个非常重要的概念,它允许我们在运行时动态地创建一个实现了特定接口的代理对象,以此来拦截并扩展原有对象的行为。动态代理在很多场景下都有应用,比如AOP(面向切面编程)、事件...

    JDK动态代理简单示例

    JDK动态代理是Java编程中一个非常重要的特性,它允许我们在运行时创建具有特定接口的代理类实例。这种技术在很多场景下都非常有用,比如在AOP(面向切面编程)中实现方法拦截、日志记录、事务管理等。下面我们将深入...

    jdk 的动态代理和CGLIB代理

    jdk 的动态代理和CGLIB代理

    JDK动态代理 spring aop 的原理

    在Java编程领域,JDK动态代理是实现动态创建代理对象的一种技术,它是Java标准库提供的一种强大工具。Spring AOP(面向切面编程)则是一种流行的应用框架,它利用动态代理来实现对业务代码的切面增强,如日志、事务...

    AOP之JDK动态代理和CGLib动态代理

    CGLib的优点是它可以代理任何类,无需目标对象实现接口,但相比JDK动态代理,它的运行效率较低,且由于生成了子类,可能会引起类加载和内存占用的问题。 **Spring AOP的应用**: 在Spring框架中,AOP主要用于日志...

    jdk动态代理和CGlib动态代理

    JDK动态代理和CGlib动态代理是Java中实现这一目标的两种主要方式。 ### JDK动态代理 JDK动态代理基于Java的接口实现。如果一个类实现了至少一个接口,我们就可以为这个类创建一个动态代理。动态代理通过`java.lang....

    java代理机制 JDK动态代理和cglib代理 详解

    本文将深入探讨两种主要的Java代理实现:JDK动态代理和CGLIB代理。 一、JDK动态代理 JDK动态代理基于接口实现,它要求被代理的类必须实现至少一个接口。在运行时,Java会动态地创建一个新的类,这个类实现了与原始...

    代理模式,JDK动态代理,SpringAOP来龙去脉

    在Java中,我们可以使用JDK的动态代理或者Spring AOP来实现代理模式。 JDK动态代理主要依赖于`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口。Proxy类是生成代理对象的工厂,而...

    JDK动态代理和CGLIB代理

    JDK动态代理和CGLIB代理是两种常用的实现方式。 首先,我们来看看JDK动态代理。JDK动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类用于创建一个代理对象...

    spring jdk动态代理

    Spring AOP允许我们通过代理来实现横切关注点,如日志、事务管理等,而JDK动态代理则是Spring AOP实现的一种方式。本文将深入探讨Spring如何利用JDK动态代理技术来实现这一功能,并通过实例解析其底层实现。 首先,...

    Jdk动态代理和cglib动态代理原理

    - **CGLIB代理**适用于目标类没有接口或者不希望修改原有接口的情况,其性能通常优于JDK代理,因为它是基于字节码生成的子类,而JDK代理需要反射调用接口方法。 在实际开发中,如Spring AOP框架就同时支持JDK和...

    模拟JDK动态代理内部实现

    在本文中,我们将深入探讨如何模拟JDK的动态代理内部实现。 首先,我们需要了解JDK动态代理的基础知识。Java中的动态代理通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口实现。`Proxy...

    java jdk 动态代理 演示demo

    Java JDK 动态代理是一种强大的特性,它允许我们在运行时创建代理对象,这些代理对象可以扩展或增强已存在的接口实现。动态代理在处理AOP(面向切面编程)场景、事件监听、性能监控等方面有着广泛的应用。下面我们将...

    CGLIB 和 JDK生成动态代理类的区别

    安全性方面,由于JDK动态代理遵循接口,所以在类型检查和编译时期就能发现问题。而CGLIB在运行时生成子类,可能导致运行时异常,例如权限问题或不可预期的行为。 在实际应用中,Spring框架就同时使用了JDK动态代理...

Global site tag (gtag.js) - Google Analytics