且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我可以覆盖 Java 中的私有方法吗?

更新时间:2022-11-23 14:54:42

私有方法不会被继承,也不能以任何方式被覆盖.谁告诉你可以通过反思来做到这一点,要么是在说谎,要么是在谈论其他事情.

Private methods are not inherited and cannot be overridden in any way. Whoever told you you can do it with reflection was either lying or talking about something else.

但是,您可以像这样访问调用 printInt 的任何子类的私有方法 getInt:

However, you can access the private method getInt of whatever subclass is invoking printInt like so:

public void printInt() throws Exception {
    Class<? extends SuperClass> clazz = getClass();
    System.out.println("I am " + clazz + ". The int is " +
                       clazz.getMethod("getInt").invoke(this) );
}

这将具有从超类的 printInt 调用子类的 getInt 方法的效果.当然,现在如果子类声明getInt,这将失败,所以你必须添加一个检查才能处理正常"的子类不t 尝试覆盖"私有方法:

This will have the effect of the subclass' getInt method being called from the superclass' printInt. Of course, now this will fail if the subclass doesn't declare a getInt, so you have to add a check to be able to handle "normal" subclasses that don't try to "override" a private method:

public void printInt() throws Exception {
    Class<? extends SuperClass> clazz = getClass();

    // Use superclass method by default
    Method theGetInt = SuperClass.class.getDeclaredMethod("getInt");

    // Look for a subclass method
    Class<?> classWithGetInt = clazz;
    OUTER: while( classWithGetInt != SuperClass.class ){

        for( Method method : classWithGetInt.getDeclaredMethods() )
            if( method.getName().equals("getInt") && method.getParameterTypes().length == 0 ){
                theGetInt = method;
                break OUTER;
            }

        // Check superclass if not found
        classWithGetInt = classWithGetInt.getSuperclass();
    }

    System.out.println("I am " + classWithGetInt + ". The int is " + theGetInt.invoke(this) );
}

您仍然需要更改超类代码才能使其工作,并且由于您必须更改超类代码,因此您应该将 getInt 上的访问修饰符更改为 protected进行反射 hack-arounds.

You still have to change superclass code to make this work, and since you have to change superclass code, you should just change the access modifier on getInt to protected instead of doing reflection hack-arounds.