什么是默认访问修饰符?

时间:2010-08-20 10:35:35

标签: java access-specifier

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

12 个答案:

答案 0 :(得分:111)

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

正如mdma指出的那样,接口成员却不是这样,默认为“公共”。

请参阅Java's Access Specifiers

答案 1 :(得分:77)

默认说明符取决于上下文。

对于类和接口声明,默认值为package private。这属于protected和private,只允许同一个包中的类访问。 (受保护是这样的,但也允许访问包外的子类。)

class MyClass   // package private
{
   int field;    // package private field

   void calc() {  // package private method

   }
}

对于接口成员(字段和方法),默认访问权限是公共的。但请注意,接口声明本身默认为package private。

interface MyInterface  // package private
{
   int field1;         // static final public

   void method1();     // public abstract
}

如果我们有声明

public interface MyInterface2 extends MyInterface
{

}

使用MyInterface2的类可以从超级接口看到field1和method1,因为它们是公共的,即使它们看不到MyInterface本身的声明。

答案 2 :(得分:14)

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

答案 3 :(得分:9)

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

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

答案 4 :(得分:8)

这取决于事物是什么。

  • 默认情况下,顶级类型(即未在其他类型中声明的类,枚举,接口和注释类型)为 package-private 。 (JLS §6.6.1

  • 在类中,默认情况下,所有成员(表示字段,方法和嵌套类型声明)和构造函数都是 package-private 。 (JLS §6.6.1

    • 当类没有显式声明的构造函数时,编译器会插入一个默认的零参数构造函数,该构造函数具有与类相同的访问说明符。 (JLS §8.8.9)默认构造函数通常是错误的,因为它总是公开的,但in rare cases不等同。
  • 在枚举中,构造函数默认为私有。实际上,枚举结构必须是私有的,将它们指定为公共或受保护是错误的。枚举常量始终为 public ,并且不允许任何访问说明符。枚举的其他成员默认为 package-private 。 (JLS §8.9

  • 在接口和注释类型中,默认情况下,所有成员(再次,即字段,方法和嵌套类型声明)都是 public 。实际上,接口和注释类型的成员必须是公共的,将它们指定为私有或受保护是错误的。 (JLS §9.3 to 9.5

  • 本地类是在方法,构造函数或初始化程序块中声明的命名类。它们范围限定为{ .. }块,在这些块中声明它们,并且不允许任何访问说明符。 (JLS §14.3)使用反射,您可以从其他地方实例化本地类,它们是包私有,但我不确定该详细信息是否在JLS中。

  • 匿名类是使用new创建的自定义类,它直接在表达式中指定类主体。 (JLS §15.9.5)它们的语法不允许任何访问说明符。使用反射,您可以从其他地方实例化匿名类,并且它们和它们生成的构造函数都是 package-private ,尽管我不确定该细节是否在JLS中。

    < / LI>
  • 实例和静态初始化程序块在语言级别(JLS §8.6 & 8.7)没有访问说明符,但静态初始化程序块实现为名为<clinit>JVMS §2.9)的方法,因此该方法必须在内部具有一些访问说明符。我检查了javac和Eclipse编译器使用十六进制编辑器编译的类,发现两者都生成 package-private 方法。但是,您无法在语言中调用<clinit>(),因为<>字符在方法名称中无效,并且反射方法是硬连线以拒绝其存在,因此有效地访问说明符是无权访问。在类初始化期间,该方法只能由VM调用。 Instance 初始化程序块不是作为单独的方法编译的;他们的代码被复制到每个构造函数中,因此即使通过反射也无法单独访问它们。

答案 5 :(得分:3)

有关详细信息,请参阅here。默认值不是private / public / protected,而是完全不同的访问规范。它没有被广泛使用,我更喜欢在我的访问定义中更具体。

答案 6 :(得分:3)

默认访问说明符是。类可以访问同一包中其他类的成员。但是在包外面它显示为私有

答案 7 :(得分:3)

以下是关于Java创建者James Gosling访谈的包级别可见性的引用:

  

Bill Venners :Java有四个访问级别。默认是包。一世   一直想知道是否方便使用包访问权限   因为C ++人已经知道的三个关键词   是私人的,受保护的,公开的。或者,如果你有一些特别的   你认为包裹访问应该是默认的原因。

     

James Gosling :一个包通常是一组包含的东西   写在一起。所以我一般可以做两件事之一。   一个是强迫你总是输入一个给你的关键字   域。或者我可以有一个默认值。然后问题是,   什么是明智的默认?我倾向于追求最少的东西   危险的事情。

     

因此公开制作默认会非常糟糕。   如果是私有,那么制作默认可能是件坏事   只是因为人们实际上并不经常写私人方法。   受保护的同样的事情。并在查看一堆代码   我有,我认为最常见的事情是相当安全的   在包中。并且C ++没有关键字,因为   他们没有包装的概念。

     

但我喜欢它而不是朋友的想法,因为和朋友在一起   你有必要列举你所有的朋友,以及如果   你在包中添加了一个新类,那么你通常最终不得不这样做   去那个包里的所有课程并更新他们的朋友,   我一直觉得这是一个完全痛苦的屁股。

     

但朋友列表本身会导致某种版本问题。和   所以有一个友好阶级的概念。这是件好事   我把它作为默认 - 我将解决问题所以应该做什么   关键字是?

     

有一段时间,实际上有一个友好的关键字。但因为所有的   其他人从&#34; P开始,&#34;这是&#34; phriendly&#34;使用&#34; PH。&#34;但那是   只有在那里可能有一天。

http://www.artima.com/intv/gosling2P.html

答案 8 :(得分:3)

默认是一个关键字,用作方法和变量的访问修饰符。
使用此访问修饰符会使您的类,变量,方法或构造函数可从自己的类或包中访问,如果不存在访问修饰符,也将对其进行设置。

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

Official Documentation

答案 9 :(得分:2)

更新 Java 8 default关键字的使用情况: 正如许多其他人已经注意到默认可见性(无关键字)

  

该字段可以从同一个包内访问   阶级属于。

不要与新的 Java 8 功能(Default Methods)混淆,后者允许接口在标有default关键字时提供实现。

请参阅:Access modifiers

答案 10 :(得分:1)

有一个名为&#34的访问修饰符;默认&#34;在JAVA中,它允许仅在该包中直接创建该实体。

这是一个有用的链接:

Java Access Modifiers/Specifiers

答案 11 :(得分:-2)

首先让我说一件事没有这样的术语和#34;访问说明符&#34;在java中。我们应该将所有内容称为&#34;修饰符&#34;。我们知道final,static,synchronized,volatile ....被称为修饰符,即使是Public,private,protected,default,abstract也应该被称为修饰符。默认值是这样的修饰符,其中不存在物理存在但没有放置修饰符,那么它应该被视为默认修饰符。

为证明这一点,举一个例子:

public class Simple{  
    public static void main(String args[]){  
     System.out.println("Hello Java");  
    }  
}  

输出将是:Hello Java

现在将public更改为private并查看您获得的编译器错误:   它说&#34;修改器私有这里不允许&#34;   什么结论是有人可能是错的或一些教程可能是错误的但编译器不能错。 所以我们可以说java中没有术语访问说明符,一切都是修饰符。