Answers:
默认可见性称为“ package-private”(尽管您不能显式使用此属性),这意味着可以从该类所属的同一包内部访问该字段。
正如mdma指出的那样,接口成员的情况并非如此,其默认值为“ public”。
请参阅Java的访问说明符
默认说明符取决于上下文。
对于类和接口声明,默认为包私有。这介于受保护的和私有的之间,仅允许访问同一包中的类。(受保护就是这样,但也允许访问包外部的子类。)
class MyClass // package private
{
int field; // package private field
void calc() { // package private method
}
}
对于接口成员(字段和方法),默认访问权限是public。但是请注意,接口声明本身默认为私有包。
interface MyInterface // package private
{
int field1; // static final public
void method1(); // public abstract
}
如果我们有声明
public interface MyInterface2 extends MyInterface
{
}
然后,使用MyInterface2的类可以从超级接口查看field1和method1,因为它们是公共的,即使它们看不到MyInterface本身的声明。
/* pp */
)只是默认访问的方便名称。不是JLS名称。
默认可见性(无关键字)为package,这意味着它可用于同一包中的每个类。
有趣的一点是,protected不仅限制了子类的可见性,而且还限制了同一包中的其他类的可见性
这取决于事物是什么。
默认情况下,顶级类型(即未在另一种类型内声明的类,枚举,接口和注释类型)是程序包专用的。(JLS§6.6.1)
在类中,默认情况下,所有成员(表示字段,方法和嵌套类型声明)和构造函数都是程序包私有的。(JLS§6.6.1)
在枚举中,构造函数默认为私有。实际上,枚举构造器必须是私有的,并且将它们指定为公共或受保护是错误的。枚举常量始终是public,并且不允许任何访问说明符。枚举的其他成员默认情况下是包私有的。(JLS§8.9)
在接口和注释类型中,默认情况下,所有成员(同样,这意味着字段,方法和嵌套类型声明)都是公共的。实际上,接口和注释类型的成员必须是公共的,并且将它们指定为私有或受保护是错误的。(JLS§9.3至9.5)
本地类是在方法,构造函数或初始化程序块内声明的命名类。它们的作用域是声明它们的{
.. }
块,并且不允许任何访问说明符。(JLS§14.3)使用反射,您可以从其他地方实例化本地类,并且它们是程序包专用的,尽管我不确定JLS中是否包含该细节。
匿名类是创建的自定义类,可使用new
它们直接在表达式中指定类主体。(JLS§15.9.5)其语法不允许任何访问说明符。使用反射,您可以从其他地方实例化匿名类,它们和它们生成的构造函数都是包私有的,尽管我不确定该细节是否在JLS中。
实例和静态初始化块没有在语言级别(访问说明JLS第8.6节和8.7),但静态初始化块被实现为命名的方法<clinit>
(JVMS§2.9),所以该方法必须在内部,有一定的出入符。我使用十六进制编辑器检查了由javac和Eclipse的编译器编译的类,发现两者都将方法生成为package-private。但是,您不能<clinit>()
在语言中调用,因为方法名称中的<
和>
字符无效,并且反射方法被硬连线以拒绝其存在,因此有效地其访问说明符是 access。该方法只能在类初始化期间由VM调用。实例初始化程序块不会编译为单独的方法;它们的代码被复制到每个构造函数中,因此即使通过反射也无法单独访问它们。
default是一个关键字,用作方法和变量的访问修饰符。
使用此访问修饰符将使您的类,变量,方法或构造函数可从自己的类或包中访问,如果不存在访问修饰符,也将对其进行设置。
Access Levels
Modifier Class Package Subclass EveryWhere
public Y Y Y Y
protected Y Y Y N
default Y Y N N
private Y N N N
如果在接口中使用默认值,则可以在其中实现这种示例的方法
public interface Computer {
default void Start() {
throw new UnsupportedOperationException("Error");
}
}
但是,仅适用于Java 8版本
以下是Java创造者James Gosling访谈中有关程序包级别可见性的报价:
Bill Venners:Java具有四个访问级别。默认为包。我一直想知道将程序包访问设置为默认值是否方便,因为C ++的人们已经知道这三个关键字分别是private,protected和public。或者,如果出于某些特殊原因,您认为应该将程序包访问权限作为默认访问权限。
詹姆斯·高斯林:程序包通常是将某些东西写在一起的一组东西。所以一般来说,我可以做两件事之一。一种是强迫您始终输入可以提供域的关键字。否则我可能有一个默认值。然后问题是,是什么使明智的违约呢?而且我倾向于最危险的事情。
因此,公开默认是一件很不好的事情。如果仅因为人们实际上并不经常编写私有方法,那么私有默认设置可能是一件坏事。与受保护的事物相同。在查看我拥有的一堆代码时,我认为最合理的最普通的东西是包装。而且C ++对此没有关键字,因为它们没有包的概念。
但是我喜欢它而不是朋友的概念,因为与朋友一起您必须枚举您所有朋友的身份,因此,如果将新类添加到程序包中,则通常最终必须去所有的朋友。包中的课程并更新他们的朋友,我一直发现这完全是一个痛苦。
但是朋友列表本身会引起某种版本问题。因此就有了友善阶级的概念。我将默认值设为了很好的一件事-我将解决问题,所以关键字应该是什么?
有一阵子实际上是一个友好的关键字。但是因为所有其他字符都以“ P”开头,所以它以“ PH”开头。但是那只可能在那里呆了一天。
首先让我说一件事,在Java中没有“访问说明符”这样的术语。我们应该将所有内容称为“修饰符”。众所周知,最终的,静态的,同步的,易变的....被称为修饰符,甚至公共,私有,受保护,默认,抽象也应称为修饰符。默认是这样的修饰符,其中不存在物理存在但没有放置修饰符,则应将其视为默认修饰符。
为了证明这一点,请举一个例子:
public class Simple{
public static void main(String args[]){
System.out.println("Hello Java");
}
}
输出将是: Hello Java
现在将public更改为private,然后看到您遇到什么编译器错误:上面写着“此处不允许使用修饰符private”,可以得出结论:某人可能是错误的,或者某些教程可能是错误的,但是编译器不能是错误的。因此,可以说Java中没有术语“访问说明符”,所有内容都是修饰符。