Java JAR方法重写

Java JAR方法重写,java,Java,因此,我是Java新手,非常希望这里有一些建议 我有一个jarXYZ.jar,我已经将它添加到我的类路径中。这个XYZ.jar有大约4个类,即A、B、C、D。在类D中有一个方法,即私有无效方法P(),它被类a、B、C调用 现在我的项目中有一个类Main.java,它有一个方法methodr()。 现在我想用Main.java中的methodr()覆盖private void方法p()。我可以做的一件事是,我可以用Classd扩展我的Main类。但是,我必须修改类A、B、C中的方法名,我不想这样做

因此,我是Java新手,非常希望这里有一些建议

我有一个jar
XYZ.jar
,我已经将它添加到我的类路径中。这个
XYZ.jar
有大约4个类,即
A、B、C、D
。在
类D
中有一个方法,即
私有无效方法P()
,它被
类a、B、C
调用

现在我的
项目中有一个类
Main.java
,它有一个方法
methodr()。

现在我想用
Main.java
中的
methodr()
覆盖
private void方法p()
。我可以做的一件事是,我可以用C
lassd
扩展我的
Main类。但是,我必须修改
类A、B、C
中的方法名,我不想这样做,因为所述类在jar中


因此,我想知道的是,是否有一种方法可以重写jar中存在的类的私有方法,而不更改jar中存在的调用该方法的其余类

,假设您的类
a
B
C
期望类
D
作为其构造参数:

class Main extends D {
    public static void Main(String[] args) {
        Main main = new Main();
        A a = new A(main);
        B b = new B(main);
        C c = new C(main);
    }

    public void R() { ... }

    public void P() {
        R();
    }
}
但是只有当
D
及其方法
p()
不是final,并且您的其他类本身没有实例化
D
时,这才有效


另一种昂贵的方法是使用
PowerMockito
模拟方法
D.p()
使用
Main.R()
。但这不应用于生产代码

如果您想在主类中重写类D的方法,则需要做两件事:

  • 确保您的
    Main扩展了D
    。如果Main不继承D,它就不能重写它的方法
  • 确保主类中的方法与您试图重写的方法具有完全相同的签名
  • 因此,您不应该在主类中使用名为
    R
    的方法,而应该将其重命名为名为
    p
    的方法(因为这是您试图重写的方法)。 为了避免错误,建议添加
    @覆盖
    。这将显示您是否犯了任何错误

    现在,如果您确实需要调用
    R
    (因为此方法已经被您自己的代码中的其他方法/类调用,您可以按照Lino的建议执行:

    public void R(/* parameters */) {
      P(/* parameters */);
    }
    
    @Override
    public void P(/* parameters */ ) {
      // the overriden code
    }
    
    这模仿R来覆盖p,但R的签名或其中的代码中的任何更改都会与此相矛盾

    编辑: 或者,更好的方法:

    public void R(/* parameters */) {
      // the overriden code
    }
    
    @Override
    public void P(/* parameters */ ) {
      R(/* parameters */);
    }
    

    如果提供具有相同限定名称(包+类名)的类,则可以隐藏类路径中的任何类。因此,如果这是您的设置:

    Project
    |- your.own.package
       |- Main.java
    
    Classpath:
    |-xjz.jar
        |- some.other.package
           |-A
           |-B
           |-C
           |-D
    
    通过向项目中添加具有相同限定名称的类,可以替换complete
    some.other.package.D

    Project
    |- your.own.package
       |- Main.java
    |- some.other.package
       |- D.java
    Classpath:
    |-xjz.jar
        |- some.other.package
           |-A
           |-B
           |-C
           |-D
    
    这是因为您自己的代码总是添加到类路径的开头,java解释器会按照规范顺序查找类路径中的类

    这种方法的缺点是,您需要复制不想修改的原始D类的代码。在您的示例中,您需要复制D类的代码,并确保所有方法签名都相同,以避免出现NoSuchMethodException。然后您只需按如下方式更改p方法:

    private void P(){
      Main.R();
    }
    

    你所需要做的就是在Main.java类中重命名你的方法。@Stultuske:你介意详细说明一下吗?我没有完全明白你的意思。我将在回答中进行总结。你能详细说明为什么你需要更改类a、B、C\中的方法吗?因为你要重写的方法是私有的,所以如果不更改jar本身。提供了更多的信息。我真的很抱歉。但是我没有提到D类中
    方法P
    访问修饰符是私有的,而不是公共的。让我编辑我的帖子。再次非常抱歉。在这种情况下,你根本无法覆盖它。除了在jar中实际进行更改,还有其他选择吗?@Phillip没有。但是:可能有一个原因,为什么它被声明为私有,以及为什么它不可能被更改/继承。我在写文章时犯了一个错误。我忘了提到父类的方法P是私有方法而不是公共方法。请看我的编辑post@Stultuske你说得对,“超控”这里的单词不对。我编辑了我的答案。