Java - 在JVM中修改Object类的toString()

Man*_*ban -2 java proxy tomcat mockito javassist

在JVM中,我想改变Object类的toString方法的行为getClass().getName();而不是返回getClass().getName() + "@" + Integer.toHexString(hashCode());

我尝试过Javassist的Hotswapper,但它需要在启动tomcat服务器时分配调试端口.有没有其他方法可以更改JVM中Object类的toString()的功能?

我的用例:我的JVM中的一些对象没有toString()实现.因此,采用Object.class中的基本实现,这将不是唯一的(因为哈希码).我有一个记录和测试环境,其中值必须是唯一的,然后才能自动比较它们.

Gho*_*ica 6

可能可以通过篡改实际的Object.class文件(编译你自己的版本,然后替换相应的JAR文件中的.class文件)来做到这一点.但是我会非常希望JVM能够注意到这一点,然后用手指拍打.

在JVM启动之后"稍后"执行它是完全不可能的.java.lang的类由最初的"启动"类加载器,这是所有加载到JVM,且不能更改(直到你开始建立自己的JVM).所以之前的任何代码是由JVM调用,它已经加载java.lang.Object中,并从它在文件系统中找到的.class文件实施.

正如评论所暗示的那样,真正的答案是:你正在走错了兔子洞.

可能有数百个(如果不是数千个)内部API或第三方库假设默认toString()结果看起来像它.当然,依靠这个假设是一个坏主意,但是,你的改变可能会破坏这些代码.

除此之外,真正的答案是:当您不喜欢默认行为时,请更改那些对您而言重要的类.

更新1,另一种(理论)方法:可能挂钩到类加载器,以便在加载特定的"用户类"时,拦截该进程,并添加生成的toString()方法(可能是OP尝试使用javaasist).但是OP希望在tomcat上下文中执行此操作,并且tomcat具有自己的类加载器的复杂层次结构.这个选项也没有现实的机会!即使你完全控制了类加载器,我们也在谈论"黑魔法伏都教"风格.你为教育项目所做的事情,而不是那些必须在现实世界中稳健可靠地运作的东西.

更新2,关于更新的要求.OP基本上想要改变类的特定行为而不重新编译它们.但鉴于其他要求,这在这里根本不可能.在Java中启用此类"动态"的所有选项都不适合现实世界的生产环境.

因此,答案只是坚持下去:OP要求的理论上可能是什么,但是出于所有实际目的,这是不可行的.