25
class MyClass 
{
    public static final int num=90;
}
  • 为什么允许我在非公共类中创建公共成员?
  • 是否有另一种我不知道的访问该成员的方法(除了通过类名)?
4

4 回答 4

18

由于您的问题是关于members,我将同时解决字段和方法(非静态;Anthony Accioly 的回答涉及另一个很好的用例,其中也包括静态字段)。

虽然在许多情况下,这只是语言语法的模棱两可的结果(特别是:非公共类中的公共字段,如您的示例片段中),但有很好的理由需要能够在非公共类中使用公共方法。公开课。

扩展Mik378 的答案,例如,考虑以下(人为的示例):

import ...;

class BleebleAscendingComparator implements Comparator<Bleeble> {
    @Override public int compare (Bleeble o1, Bleeble o2) { ... }
}

class BleebleDescendingComparator implements Comparator<Bleeble> {
    @Override public int compare (Bleeble o1, Bleeble o2) { ... }
}

public class BleebleView {  
    public enum SortMode { ASC, DESC };
    public Comparator<Bleeble> getDisplayOrderComparator (SortMode mode) {
        if (mode == SortMode.ASC)
            return new BleebleAscendingComparator();
        else
            return new BleebleDescendingComparator();
    }
}

您不能Comparator直接在该上下文之外实例化其中一个实现,但它们必须覆盖 的公共方法Comparator,并且它们的功能可以通过Comparator接口访问。

同样的推理也适用于例如内部类privateprotected如果您无法声明方法public,您将无法覆盖public它们继承的接口或它们扩展的类的方法。

实际例子:

  • 每次覆盖匿名内部类中的公共方法时(例如,每次覆盖匿名内部类时public void actionPerformed)都会使用它ActionListener

  • 考虑任何您想存储在HashMap. 您将覆盖公共equals()hashCode()该非公共类,并且HashMap无论该类是非公共的事实如何,都可以访问它们。

  • 经常被覆盖public toString()的是潜在非公共类的公共成员的另一个常见示例。

  • 一个更复杂的例子是java.sql.DriverManagerjava.sql.Driver中的使用(一般来说,工厂类型的设计会大量使用这个概念)——SQL 驱动程序实现可能不会使实现类公开(例如,Oracle驱动程序产生非公开的)对象)。Connection

  • 还有更多……如果您留意这方面的例子,您会惊讶于它的普遍性!

于 2014-03-03T01:15:01.937 回答
5

不要忘记具有default访问权限的类可以被public同一个包中的类子类化。

package package1;

class MyDefaultClass {

    public static final int MY_CONSTANT = 0xCAFEBABE;
}

public class PublicExporter extends MyDefaultClass {

}

现在public该类充当桥梁,您可以使用MyDefaultClass public其他包中的成员。

package package2;

import package1.PublicExporter;

public class Consumer {
    public static void main(String[] args) {
        System.out.printf("%x\n", PublicExporter.MY_CONSTANT);
    }
}

消费者甚至可以导入静态成员:

import static package1.PublicExporter.MY_CONSTANT;

public class Consumer {
    public static void main(String[] args) {
        System.out.printf("%x\n", MY_CONSTANT);
    }
}
于 2014-03-03T01:17:37.167 回答
3

public属于封闭类的方法返回对其具有默认范围的内部类A的引用(public超类型引用,如接口)时,外部客户端(外部的包)只能调用的方法,但不能创建自己的新实例.BABB

如果B' 的方法不是public,则外部客户端无法访问它们,更糟糕的是:由于没有很好地实现其接口,因此会导致编译错误。

这种建模在特定上下文中可能很有用,以改进代码设计。

于 2014-03-03T00:44:04.593 回答
0

当你声明一个变量public时,它基本上就变成了 ; 它可以在整个程序中看到,无需任何特殊的 getter/setter。类不一定需要public为了它的成员也是公共的。

请记住,在 Java 中,每个编译单元(.file)只能有 1 个公共类java,并且该公共类需要与编译单元具有相同的名称。除此之外,它不“拥有”关键字 public 的所有权。

num您声明为publicstatic允许您说 System.out.println(MyClass.num)的事实。该public属性允许您直接获取num变量。因此,您不必创建num为您返回的方法。因为是公开的,所以也可以说

      MyClass mc = new MyClass();
      System.out.println(mc.num);

但是,由于您还添加了static声明,因此您只能通过类名访问它,即 MyClass.num

要点:公共变量可以存在于任何类型的类中,它们允许您访问它们而无需 getter 和 setter。然而,公共类并不是唯一可以拥有公共变量的类。

于 2014-03-03T00:43:29.653 回答