当它们具有相同接口的相同实现时,将执行哪种方法?

时间:2019-04-02 11:05:16

标签: java

有一个名为

的方法的接口

foo(boolean arg1, String arg2);

此外,我有两个实现此方法的类。现在,当我从接口调用foo方法时,它如何决定选择哪种实现?

这两个实现采用相同的参数并返回相同的对象,但是实现不同。

3 个答案:

答案 0 :(得分:4)

致电时

a.foo(b, c);

它查看a所指向的对象的类型,而不是引用的类型,并调用该类型实现的方法。

最初,它使用一个虚拟查找表,您可以对其进行映像处理,因此价格昂贵,因此在Oracle / OpenJDK JVM中,它可以根据使用情况动态内联多达两个虚拟方法,因此看起来更像这样。

if (a instanceof Type1) {
    ((Type1) a).foo(b, c);
} else (a instanceof Type2) {
    ((Type2) a).foo(b, c);
} else {
    a.foo(b, c); // do a full vtable lookup.
}

答案 1 :(得分:3)

您不能在接口上调用方法...您需要在一个对象(实现您的接口的类的实例)上调用它们。这就是被调用的代码。

答案 2 :(得分:0)

我相信您询问有关在其他(默认)接口方法中使用接口方法的问题。

方法将基于接口变量引用的实例进行选择。这是一个小例子

class Scratch {
    public static void main(String[] args) {
        ClassA varClassA = new ClassA();
        ClassB varClassB = new ClassB();
        Bar interfaceVar = varClassA;
        interfaceVar.foo("firstCall");
        interfaceVar = varClassB;
        interfaceVar.foo("secondCall");
        varClassA.foo("call from A");
        varClassB.foo("call from B");
        interfaceVar = new Bar() { // or just interfaceVar = System.out::println
            @Override
            public void printParam(String params) {
                System.out.printf("Anonimus class: %s%n", params);
            }
        };
        interfaceVar.foo("Anonimus call");
    }

    public interface Bar {
        default void foo(String param) {
            printParam(param);
        }

        void printParam(String params);
    }

    public static class ClassA implements Bar {
        @Override
        public void printParam(String params) {
            System.out.println(String.format(
                    "Called from %s wth params: %s",
                    this.getClass().getName(),
                    params)
            );
        }
    }

    public static class ClassB implements Bar {
        @Override
        public void printParam(String params) {
            System.out.printf("param from ClassB:%s%n", params);
        }
    }
}

输出:

Called from Scratch$ClassA wth params: firstCall
param from ClassB:secondCall
Called from Scratch$ClassA wth params: call from A
param from ClassB:call from B
Anonimus class: Anonimus call

Process finished with exit code 0