哪个是Java中的默认访问说明符?

ben*_*ich 103 java access-specifier

所以我刚开始阅读一本Java书并想知道; 如果没有指定,哪个访问说明符是默认值?

Kea*_*eks 113

默认可见性称为"私有包"(尽管您不能明确使用它),这意味着可以从类所属的同一个包内访问该字段.

正如mdma指出的那样,接口成员却不是这样,默认情况下是"public".

请参阅Java的访问说明符

  • 不正确 - 对于接口成员不正确.然后默认访问是公开的 (24认同)
  • 它实际上被称为“包私有”。第三方网站不是规范性引用。您应该只引用 JLS。 (2认同)

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本身的声明.

  • @Tom - 这是正确的,JLS使用"默认访问".我本来可以写"默认是默认访问".但这似乎没有太大帮助! (10认同)

Mic*_*rdt 15

如果没有给出访问说明符,则对类和类成员进行包级访问(对此没有明确的说明符).接口方法是隐式公开的.


Joh*_*ter 9

默认可见性(无关键字)是,这意味着它可用于位于同一包中的每个类.

有趣的是,protected不会限制子类的可见性,也会限制同一个包中的其他类


Boa*_*ann 8

这取决于事物是什么.

  • 顶级类型(即,未在另一种类型中声明的类,枚举,接口和注释类型)默认为package-private.(JLS§6.6.1)

  • 在类中,默认情况下,所有成员(即字段,方法和嵌套类型声明)和构造函数都是包私有的.(JLS§6.6.1)

    • 当类没有显式声明的构造函数时,编译器会插入一个默认的零参数构造函数,该构造函数具有与该类相同的访问说明符.(JLS§8.8.9)默认构造函数通常是错误的,因为它总是公开的,但在极少数情况下,它不是等价的.
  • 在枚举中,构造函数默认是私有的.实际上,枚举构造函数必须是私有的,将它们指定为公共或受保护是错误的.枚举常量始终是公共的,并且不允许任何访问说明符.枚举的其他成员默认为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调用.实例初始化程序块不是作为单独的方法编译的; 他们的代码被复制到每个构造函数中,因此即使通过反射也无法单独访问它们.


Ama*_*nes 5

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版本

官方文件

Java中的访问修饰符