Kea*_*eks 113
默认可见性称为"私有包"(尽管您不能明确使用它),这意味着可以从类所属的同一个包内访问该字段.
正如mdma指出的那样,接口成员却不是这样,默认情况下是"public".
请参阅Java的访问说明符
mdm*_*dma 79
默认说明符取决于上下文.
对于类和接口声明,默认值为package private.这属于protected和private,只允许同一个包中的类访问.(受保护是这样的,但也允许访问包外的子类.)
class MyClass // package private
{
int field; // package private field
void calc() { // package private method
}
}
Run Code Online (Sandbox Code Playgroud)
对于接口成员(字段和方法),默认访问是公共的.但请注意,接口声明本身默认为包私有.
interface MyInterface // package private
{
int field1; // static final public
void method1(); // public abstract
}
Run Code Online (Sandbox Code Playgroud)
如果我们有声明
public interface MyInterface2 extends MyInterface
{
}
Run Code Online (Sandbox Code Playgroud)
然后,使用MyInterface2的类可以从超级接口看到field1和method1,因为它们是公共的,即使它们看不到MyInterface本身的声明.
这取决于事物是什么.
顶级类型(即,未在另一种类型中声明的类,枚举,接口和注释类型)默认为package-private.(JLS§6.6.1)
在类中,默认情况下,所有成员(即字段,方法和嵌套类型声明)和构造函数都是包私有的.(JLS§6.6.1)
在枚举中,构造函数默认是私有的.实际上,枚举构造函数必须是私有的,将它们指定为公共或受保护是错误的.枚举常量始终是公共的,并且不允许任何访问说明符.枚举的其他成员默认为package-private.(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>()
在语言中调用,因为<
和>
字符在方法名称中无效,并且反射方法是硬连线以拒绝其存在,因此有效地访问说明符是无法访问的.在类初始化期间,该方法只能由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
Run Code Online (Sandbox Code Playgroud)
如果您在接口中使用默认值,则可以在其中实现这种示例的方法
public interface Computer {
default void Start() {
throw new UnsupportedOperationException("Error");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,仅适用于Java 8版本