Java Reflect / AOP覆盖超类型私有方法

时间:2010-12-14 13:53:43

标签: java reflection aop

是否可以在Java中“覆盖”超类的私有方法?

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

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

4 个答案:

答案 0 :(得分:4)

即可。你可以用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);
}

创建一个方面,强制超类实现该接口并添加一个顾问来调用它。

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);
    }
}

现在,如果您构造一个Overrider对象并调用echo方法,那么您将获得Overriders safeContent方法的输出。

答案 1 :(得分:3)

您没有合法的方法来执行此操作。但我可以建议你以下解决方案。

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

答案 2 :(得分:2)

  

是否可以在Java中“覆盖”超类的私有方法?

我不认为使用Reflection会有一个调整,它会打破OOP那里

答案 3 :(得分:0)

是的,这是可能的,但你不应该这样做,因为它与SOLID原则之一相矛盾。更确切地说,它与Liskov substitution principle相矛盾。

  

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

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

Java因此而限制它。