class MyClass
{
public static final int num=90;
}
- 为什么允许我在非公共类中创建公共成员
- 有没有其他我不知道的访问该成员的方法(除了通过类名)
由于您的问题是关于成员,我将同时讨论字段和方法(非静态;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
接口访问它们的功能。
同样的推理适用于例如private
或protected
内部类。如果不能声明方法public
,那么就无法覆盖它们继承的接口或扩展的类的public
方法。
实际示例:
每次覆盖匿名内部类中的公共方法时(例如,每次覆盖匿名
ActionListener
中的public void actionPerformed
时),都会使用此。考虑任何要存储在
HashMap
中的非公共类。您将覆盖该非公共类中的公共equals()
和hashCode()
,并且HashMap
的实现可以访问它们,而不管该类是非公共的。经常被重写的
public toString()
是潜在非公共类的公共成员的另一个常见示例。一个更复杂的例子是在java.sql.DriverManager中使用
java.sql.Driver
(通常,工厂类型的设计会大量使用这个概念)——sql驱动程序实现可能不会公开实现类(例如,Oracle驱动程序生成非公共的Connection
对象)。更多。。。如果你留意这方面的例子,你会惊讶于它的普遍性!
不要忘记,具有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("%xn", PublicExporter.MY_CONSTANT);
}
}
消费者甚至可以导入静态成员:
import static package1.PublicExporter.MY_CONSTANT;
public class Consumer {
public static void main(String[] args) {
System.out.printf("%xn", MY_CONSTANT);
}
}
当属于封闭类A
的public
方法向其具有默认作用域的内部类B
返回引用(public
超类型引用,类似于接口)时,外部客户端(在A
的包之外)只能调用B
的方法,但不能创建自身的B
的新实例。
如果B
的方法不是public
,则外部客户端无法访问它们,更糟糕的是:由于没有很好地实现其接口,将导致编译错误。
这种建模在特定的上下文中可能很有用,可以改进代码设计。
当您声明一个变量public
时,它本质上就是这样;它可以在整个程序中看到,而无需任何特殊的getter/setter。该类不一定需要是public
才能使其成员也是公共的。
请记住,在Java中,每个编译单元(.java
文件)只能有一个公共类,并且该公共类需要与编译单元具有相同的名称。除此之外,它并不"拥有"关键字public的所有权。
您将num
声明为public
和static
,这一事实允许您说出System.out.println(MyClass.num)。public
属性允许您直接获取num
变量。因此,您不必创建一个方法来为您返回num
。因为它是公开的,你也可以说
MyClass mc = new MyClass();
System.out.println(mc.num);
但是,由于您还添加了static
声明,因此应该仅通过类名访问它,即MyClass.num
要点:公共变量可以存在于任何类型的类中,它们允许您在不需要getter和setter的情况下访问它们。然而,公共类并不是唯一可以拥有公共变量的类。