【问题标题】:Variables in private interface私有接口中的变量
【发布时间】:2013-06-05 09:24:27
【问题描述】:

我试图测试 private interfaces 的工作,并编写了下面的代码。我可以理解,如果我们不希望任何其他类实现它们,那么可能会出现声明 private interfaces 的情况,但是变量呢?接口变量隐式为public static final,因此即使接口被声明为私有,我也能够访问它们。这可以在下面的代码中看到。

 public class PrivateInterfaceTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        TestingInterfaceClass test = new TestingInterfaceClass();
        TestingInterfaceClass.inner innerTest = test.new inner();

        System.out.println(innerTest.i);

    }

}

class TestingInterfaceClass {

    private interface InnerInterface {
        int i = 0;
    }

    class inner implements InnerInterface {

    }
}

这是否意味着我们永远无法真正拥有private interface?如果我们可以访问private interface 之外的变量,那么拥有private interface 真的有意义吗?

编辑: 只是想补充一下,如果我们有私有内部类,就不会出现同样的情况。内部类中的私有变量永远不会暴露。

【问题讨论】:

  • 我认为所有这些代码都在同一个文件中?
  • 是的,所有代码都在同一个文件中。
  • 对我来说,私有接口根本没有意义,尽管可访问的 int 很奇怪。
  • 一个接口被设计成一个公共合约,那么隐藏它的意义在哪里?
  • @joerx:如果您不希望自己的合同对全世界可见,那该怎么办?

标签: java interface private


【解决方案1】:

接口变量是隐式的public static final,但是你不能访问这个变量,因为你不能访问包含这些变量的接口,你已经声明为私有。首先你需要能够看到界面,然后进入界面的内容。

【讨论】:

  • true 但正如您在代码中看到的那样,我能够使用内部类绕过该私有接口并访问该变量。所以重点是为什么要有私有接口?
【解决方案2】:

如我所见,private interface InnerInterface 没有问题。它是inner 类,它位于TestingInterfaceClass 内的默认范围内,暴露了InnerInterface 的内容。如果您不希望InnerInterface 的内容为全世界所知,您还应该将所有类(特别是TestingInterfaceClass)声明为私有。

因为接口中的每个变量都是public static final,所以应该由类(实现它)负责是否应该处理从private interface继承的内容

【讨论】:

  • 假设我有一个带有私有变量的私有内部类。现在,如果我创建一个具有默认范围的内部类,那么私有变量将无法访问,不是吗?但是在界面中它仍然可以访问。这是否意味着接口永远不应该是私有的?处理这个不应该是内部类的责任。
  • 如您所说,private 成员在课堂外永远不可见。但是public 成员是。就像说如果你继承一个public 成员(来自classinterface)一样简单,它通过你是可见的。您不能从class 继承private 成员,而interface 没有private 成员。如果您的问题归结为为什么public static final 对于interface 的所有变量,请检查stackoverflow.com/questions/2430756/…
【解决方案3】:

您的会员界面是私有的。继承的静态字段不是私有的。

私有成员接口不能用作封闭顶级类或枚举之外的类型。这对于防止外部代码实现您可能希望更改的接口很有用。来自 JLS:

访问修饰符 protected 和 private 仅适用于直接封闭类或枚举声明中的成员接口(第 8.5.1 节)。

接口字段是公共的,由实现接口的类继承。来自 JLS:

一个类从它的直接超类和直接超接口继承超类和超接口的所有非私有字段,这些字段都可以被类中的代码访问,并且不会被类中的声明隐藏。

如果您想让该字段只能在实现成员接口的类中访问,您可以将其声明放在封闭的顶级范围内。

class TestingInterfaceClass {
    private static final int i = 0;

    private interface InnerInterface {
        // ...
    }

    class inner implements InnerInterface {
        // ...
    }

}

【讨论】:

  • 而且不可能将字段设为私有,不是吗?所以我们不应该有私有接口。你同意吗?
  • 私有成员接口是合法且有用的。您可以阻止外部实现,这允许您根据需要更改接口,而不会破坏顶级类外部的代码。字段的继承与类型的可访问性是一个单独的问题。
  • 我同意你的观点,但是接口允许我们只隐藏方法,我们无法在接口中隐藏任何变量信息。这不是说接口永远不是真正私有的吗?并且是半私人的。
  • 接口上的 private 限定符限制对 type 的访问,而不是方法或字段,它们都是隐式公共的。 (顺便说一句,有关如何避免在 TestingInterfaceClass 外部访问私有字段,请参阅上面的编辑。)
【解决方案4】:

即使允许,我们也不需要(也不应该使用)实例来访问静态字段。

以下是访问它的方式-

System.out.println(TestingInterfaceClass.inner.i);
//note you cannot access the InnerInterface like this here because it's private 

inner 继承了公共静态字段i,并且i 应该在inner 本身可见的地方可见。

通常,接口用于公开对象的行为,而实现是隐藏的。但在你的情况下,你正在尝试相反的事情。

【讨论】:

    猜你喜欢
    • 2015-07-03
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 2020-06-12
    • 2012-07-26
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    相关资源
    最近更新 更多