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

发布于 2021-01-31 15:22:08

我知道我可以使用反射来调用私有方法,并获取或设置私有变量的值,但是我想重写一个方法。

public class SuperClass {

    public void printInt() {
        System.out.println("I am " + getClass() + ". The int is " + getInt());
    }

    private int getInt() {
        return 1;
    }
}

public class SubClass extends SuperClass {

    public static void main(String[] args) {
        (new SubClass()).printInt();
    }

    public int getInt() {
        return 2;
    }
}

我希望main方法SubClass
可以打印出来2,但是可以打印出来1。我听说这可以通过反思来完成,但是我不知道怎么做。如果不是反思,有谁知道另一种方式吗?(除了使方法SuperClass.getInt()受保护,或者将printInt()方法复制并粘贴到SubClass。)如果实际上无法覆盖私有方法,是否可以在其上放置某种触发器以在子类之前或之后调用我的子类中的方法?私有方法执行后?

关注者
0
被浏览
92
1 个回答
  • 面试哥
    面试哥 2021-01-31
    为面试而生,有面试问题,就找面试哥。

    私有方法不会被继承,并且不能以任何方式覆盖。谁告诉过您您可以进行反思,那就是撒谎或谈论其他事情。

    但是,您可以访问getInt任何子类正在调用的private方法,printInt如下所示:

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

    这将具有getInt从超类调用子类的方法的效果printInt。当然,如果子类 声明a
    ,现在将失败getInt,因此您必须添加检查以处理“正常”子类,而不试图“覆盖”私有方法:

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

    您仍然必须更改超类代码才能使其正常工作,并且由于必须更改超类代码,因此应该只将access修饰符更改为getIntprotected而不是进行反射式修改。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看