接口中的默认方法,但仅限于静态final字段。

7
我知道接口中的所有字段都是隐式静态和不可变的。在Java 8之前,这是有意义的。
但是随着默认方法的引入,接口也具有抽象类的所有功能。因此,非静态和非不可变字段也是必要的。
但是当我尝试正常声明字段时,默认情况下它变为静态和不可变。 在Java 8中有没有一种声明非静态和非不可变字段的方式
或者我完全误解了什么?

非静态字段是接口和抽象类之间主要的区别。 - Louis Wasserman
4个回答

13

在Java接口中,所有字段都是public static final

即使添加了默认方法,引入可变字段到接口中仍然没有意义。

默认方法的添加是为了接口演化的原因。可以向接口添加新的默认方法,但只有当实现使用已定义的接口方法时才有意义:

public interface DefaultMethods {

    public int getValue();

    public default int getValueIncremented() {
        if (UtilityMethod.helper()) { // never executed, just to demonstrate possibilities
            "string".charAt(0); // does nothing, just to show you can call instance methods
            return 0;
        }

        return 1 + getValue();
    }

    public static class UtilityMethod {

        public static boolean helper() {
            return false;
        }
    }
}

1
那么你的意思是默认方法的目的只是包括现有方法的变体,而不是引入需要操作对象状态的全新方法吗? - Codebender
2
那就是目的。你仍然不能在接口中添加可变字段。默认方法可以调用其他对象上的静态方法和实例方法,以及接口中定义的所有抽象方法和默认方法。看看我刚刚更新的代码。 - Crazyjavahacking
@AbishekManoharan:是的,基本上就是这样。 - Louis Wasserman

3
在Java 8中,所有字段都像以前的Java版本一样是静态和不可变的。在接口中具有状态(字段)会引发问题,特别是与菱形问题相关的问题。请参见此条目,澄清行为和状态继承之间的差异。

Java 8之前是没有字段的 :) - Dmitry Ginzburg
Java自诞生以来就有接口中的字段。 - Crazyjavahacking
@DmitryGinzburg 你的意思是什么?Java一直允许在接口中声明字段(这些字段自动成为静态和常量)。 - assylias
2
@assylias 如果他们可以避免方法的问题,为什么不将其扩展到字段呢? - Chetan Kinger
@assylias 哎呀,有点临时疯狂。 - Dmitry Ginzburg
正如Chetan所提到的,我猜钻石问题已经被避免了...同样的方法也可以用于字段...如果默认方法只能操作局部变量,那么它们并不总是有用的... - Codebender

0

我强烈不建议这样做。最好使用抽象类。但如果你真的需要,可以通过一些包装类的变通方法来实现。以下是一个例子:

public interface TestInterface {

    StringBuilder best = new StringBuilder();

    default void test() {
        best.append("ok");
        System.out.print(best.toString());
    }
}

-2

很遗憾,在Java 8中,接口中不能有非public static final字段。

但我希望未来语言能够加入这个特性。

Scala允许接口具有非静态字段,这为代码重用和组合提供了比Java 8更多的可能性。


接口中可以定义字段,但只允许使用public、static和final关键字修饰。详见https://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.3 - Rohit
我的意思是那些不是公共静态常量的字段。我应该让这更清楚,抱歉。我会更新我的答案。 - M.Paniccia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接