gpt4 book ai didi

java - 类中的静态方法与接口(interface)中的默认方法具有相同的签名

转载 作者:搜寻专家 更新时间:2023-10-30 21:10:59 25 4
gpt4 key购买 nike

我有以下情况:

class C {
static void m1() {}
}

interface I {
default void m1() {}
}

//this will give compilation error : inherited method from C cannot hide public abstract method in I
class Main extends C implements I {

}

以下是我的问题:

  1. 我知道实例方法会覆盖默认方法,但是如果类中的静态方法与接口(interface)中的默认方法具有相同的签名怎么办?

  2. 如果 class C 中的静态方法 m1() 是 public 那么编译错误将是:

    静态方法 m1() 与 I 中的抽象方法冲突。

因此,当访问修饰符为默认时,它试图隐藏,而当它为公共(public)时,它是冲突的。为什么会有这种差异?它背后的概念是什么?

最佳答案

归根结底,当你遇到这样的事情时:

class Me {
public static void go() {
System.out.println("going");
}
}

这两个都是允许的:

Me.go();
Me meAgain = new Me();
meAgain.go(); // with a warning here

有趣的是,这也适用于例如:

Me meAgain = null;
meAgain.go();

我个人仍然认为这是由于兼容性而无法收回的设计缺陷 - 但我希望编译器不允许我从实例访问静态方法。

你的第一个问题本身与java-8无关,在java-8之前是这样的:

interface ITest {
public void go();
}

class Test implements ITest {
public static void go() { // fails to compile

}
}

默认方法在这里遵循相同的规则。为什么会发生这种情况实际上在堆栈溢出上有很多详细说明 - 但潜在的想法是可能这会导致调用哪个方法的混淆(想象ITest 将是一个类Test 会扩展,而你执行 ITest test = new Test(); test.go(); -> 你调用的是哪个方法?)

我认为出于同样的原因,这也是不允许的(这基本上是您的第二个问题,否则您将拥有具有相同签名的静态和非静态方法)

static class Me {
static void go() {

}

void go() {

}
}

有趣的是,这在方法引用中是固定的(我猜他们意识到再次犯同样的错误真的很糟糕):

static class Mapper {
static int increment(int x) {
return x + 1;
}

int decrement(int x) {
return x - 1;
}
}


Mapper m = new Mapper();
IntStream.of(1, 2, 3).map(m::increment); // will not compile
IntStream.of(1, 2, 3).map(m::decrement); // will compile

关于java - 类中的静态方法与接口(interface)中的默认方法具有相同的签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45582161/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com