使用反射调用超类方法而不使用其实例

时间:2012-03-19 14:23:48

标签: java reflection

请考虑以下代码,展示继承和反思:

    /*Parent class*/

    package basics;

    public class Vehicle {

        private void parentPrivateMethod() {
            System.out.println("This is the child private method");
        }

        public void print() {
            System.out.println("This is a Vehicle method");
        }

        public void overrideThisMethod() {
            System.out.println("Parent method");
        }

    }


    /*Child class*/

    package basics;

    public class Car extends Vehicle {

        private void childPrivateMethod() {
            System.out.println("This is the child private method");
        }

        public String returnCarName() {
            return "Manza";
        }

        @Override
        public void overrideThisMethod() {
            //super.overrideThisMethod();/*NOTE THIS*/
            System.out.println("Child method");
        }

    }


    /*Tester class*/
    package basics;

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;

    public class NewTester {

        /**
         * @param args
         * @throws NoSuchMethodException
         * @throws SecurityException
         * @throws InvocationTargetException
         * @throws IllegalAccessException
         * @throws IllegalArgumentException
         * @throws InstantiationException
         */
        public static void main(String[] args) throws SecurityException,
                NoSuchMethodException, IllegalArgumentException,
                IllegalAccessException, InvocationTargetException, InstantiationException {
            // TODO Auto-generated method stub

            Car carInstance = new Car();

            /* Normal method invocation */
            carInstance.overrideThisMethod();

            /* Reflection method invocation */
            Method whichMethod = Car.class.getSuperclass().getMethod(
                    "overrideThisMethod", null);
            whichMethod.invoke(carInstance, null);

            /* Work-around to call the superclass method */
            Method superClassMethod = Car.class.getSuperclass().getMethod(
                    "overrideThisMethod", null);
            superClassMethod.invoke(Car.class.getSuperclass().newInstance(), null);
        }

    }

输出(注释“注意这个”部分)是:

        Child method
        Child method
        Parent method

如果'NOTE THIS'部分未被注释,将调用超类方法,给出一个输出:

        Parent method
        Child method
        Parent method
        Child method
        Parent method

创建Car实例时,Vehicle的构造函数首先运行。因此,我相信,也会创建一个Vehicle实例,它通过'super'来引用Car实例。

问题: 如何调用'overrideThisMethod'的超类版本而不使用/ * Work-around来调用超类方法* /?

我在这里忽略了什么/做出错误的假设吗?

2 个答案:

答案 0 :(得分:3)

  

创建Car实例时,Vehicle的构造函数首先运行。因此,我相信,也会创建一个Vehicle实例,它通过'super'来引用Car实例。

这不太正确;只创建了一个对象。 Vehicle的构造函数运行是因为它是Vehicle和Car的实例。没有单独的Vehicle对象,super不是对象引用,而是关键字。例如,您不能将super作为参数传递给方法。

super关键字允许您告诉编译器您要从超类调用方法,而不检查该方法是否在子类中被重写。为此,编译器使用invokespecial JVM指令生成方法调用。通常,编译器会发出invokevirtual指令。

答案 1 :(得分:0)

如果需要运行超类公共方法,请从超类的实例中调用它。如果你想从孩子那里调用父方法,那么它首先不应该被覆盖。

Vehicle v = new Vehicle();
v.overrideThisMethod();