Java Reflect/AOP重写超类型私有方法

Java Reflect/AOP重写超类型私有方法,java,reflection,aop,Java,Reflection,Aop,是否有可能在Java中“重写”一个超类的私有方法 我希望覆盖其方法的类是第三方类,因此我无法修改源。如果有某种方法可以在类上反射地设置方法,这将是理想的 或者,如果可以拦截第三方类的私有方法,那么这将是合适的 是否有可能在Java中“重写”一个超类的私有方法 否 我不认为使用反射会有什么调整,它会破坏OOPhere你没有合法的方法来做这件事。但我可以向你推荐以下解决方案 是否确实要覆盖此方法?试着想想其他的解决办法 Java仅在编译期间检查访问权限。你感到惊讶吗?我很惊讶地发现了这个事实。因此,

是否有可能在Java中“重写”一个超类的私有方法

我希望覆盖其方法的类是第三方类,因此我无法修改源。如果有某种方法可以在类上反射地设置方法,这将是理想的

或者,如果可以拦截第三方类的私有方法,那么这将是合适的

是否有可能在Java中“重写”一个超类的私有方法


我不认为使用反射会有什么调整,它会破坏
OOP
here

你没有合法的方法来做这件事。但我可以向你推荐以下解决方案

  • 是否确实要覆盖此方法?试着想想其他的解决办法
  • Java仅在编译期间检查访问权限。你感到惊讶吗?我很惊讶地发现了这个事实。因此,您可以创建第三方类的框架(即使是空的实现)。有趣的方法应该是
    protected
    ,而不是
    private
    。现在编写子类并根据存根编译它。然后只打包子类,并尝试使用“real”类运行它。它应该会起作用。我并没有在继承方面尝试过这个技巧,但我在必须访问私有方法或字段时尝试过,它对我来说很好
  • 尝试使用动态代理来包装类并更改其实现。我不知道你到底在做什么,所以我不确定你真的能用这个方法。但我希望你能。如果没有,请返回第1或第2页

  • 。您可以使用aspectj来实现。这不是真正的覆盖,但结果将是这样

    这是你的超级班

    public class MySuperClass {
    
        private void content(String text) {
           System.out.print("I'm super " + text);
        }
    
        public void echo() {
           content("!");
        }        
    }
    
    创建包含类似方法的接口

    public interface Content {
        void safeContent(String text);
    }
    
    创建一个方面,强制超级类实现该接口,并添加一个around advisor来调用它

    public privileged aspect SuperClassAspect {
    
        void around(MySuperClass obj)
                : execution(* content(String)) && target(obj) {
    
            Object[] args = thisJoinPoint.getArgs();
            ((Content) obj).safeContent((String) args[0]);
        }
    
        // compiler requires
        public void MySuperClass.safeContent(String text) {}
    
    
        declare parents :MySuperClass implements Content;
    }
    
    创建扩展super并实现该接口的子类

    public class Overrider extends MySuperClass implements Content {
    
        public void safeContent(String text) {
            System.out.print("Not that super " + text);
        }
    }
    

    现在,如果您构造一个重写器对象并调用echo方法,您将获得重写器safeContent方法的输出。

    是的,这是可能的,但您不应该这样做,因为这与其中一个原则相矛盾。更确切地说,这是自相矛盾的

    注: 设q(x)是关于T型对象x的一个可证明的性质,然后q(y) 对于类型为S的对象y应该是可证明的,其中S是T的子类型

    换句话说,私有方法是对象的属性,所以继承类型的对象必须具有相同的属性。方法的抛出也是如此


    Java因此限制了它。

    您可以通过使用字节码(dis)汇编程序来改变字节码的可见性来实现这一点。啊,太恶心了!我认为您应该能够使用AOP的方法拦截器,而不是将调用委托给普通的
    procedure()
    ,使用反射调用方法为其创建方法实例,并在其上设置
    setAccessible()
    作为
    true
    检查方法是否有效,但是为什么不保持简单,只需在
    MySuperClass+
    上使用
    around()
    建议,拦截所需的调用或执行,并返回经过适当修改的结果呢?我想这里可能没有必要使用ITD,它可以简化,但我的目的是让它看起来像一个覆盖。