V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
ccde8259
V2EX  ›  Java

如何实现一次对象方法动态替换?

  •  
  •   ccde8259 · Jun 29, 2021 via iPhone · 2584 views
    This topic created in 1774 days ago, the information mentioned may be changed or developed.
    对于一个 Class/Interface A 而言,不妨假设 A 有一个方法叫 call(),他的一个实例 B 在实例化以后这个 call()方法能不能被动态替换?
    一个可行方法是你可以通过持有一个 Runnable 对象,在 call 方法里执行 run 方法。通过动态替换 Runnable 对象实现。以此类推 Consumer<T>,BiConsumer<T,U>对象适用于 call(T t)和 call(T t,U u)……但是更多参数呢?
    实例化以后 B 对应的 Class 已经被加载到内存里了,有没有用 Unsafe 直接操作内存方法?
    9 replies    2021-06-30 09:21:23 +08:00
    2bab
        1
    2bab  
       Jun 29, 2021
    JVM TI 应该可以
    kiracyan
        2
    kiracyan  
       Jun 29, 2021
    匿名函数?
    yitingbai
        3
    yitingbai  
       Jun 29, 2021
    可以的, 你可以了解一下动态代理
    goinghugh
        4
    goinghugh  
       Jun 29, 2021
    jvm-sanbox? btrace? 运行期不重启 JVM 的 AOP
    ccde8259
        5
    ccde8259  
    OP
       Jun 29, 2021 via iPhone
    @yitingbai 动态代理可以,相应的限制 A 只能是 Interface,如果是 Class 的话就无能为力。
    类似 CGLIB 的字节码增强技术,并不能操作实例化后的对象。
    yitingbai
        6
    yitingbai  
       Jun 29, 2021
    @ccde8259 通用的替换方法那就是 Hook 了, 我在 Android 中经常使用, 有很多 Hook 框架, 但是 Java 这块我还真没研究过, 理论上来说应该也是有的
    zifangsky
        7
    zifangsky  
       Jun 29, 2021
    还有一种思路,自定义 ClassLoader 重新加载一个修改后的实例 B
    ccde8259
        8
    ccde8259  
    OP
       Jun 29, 2021 via iPhone
    @zifangsky 如果重新加载的话,实例 B 还会是实例 B 嘛……比如 C 对象持有 B 的引用的情况下,能否在不变更这个引用的前提下实现这种替换?
    siweipancc
        9
    siweipancc  
       Jun 30, 2021 via iPhone
    :D 你是要实现一个 jrebel
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   5365 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 72ms · UTC 08:20 · PVG 16:20 · LAX 01:20 · JFK 04:20
    ♥ Do have faith in what you're doing.