哪一个是Java中的默认访问说明符?
所以我刚开始阅读一本Java书,想知道; 哪个访问说明符是默认的,如果没有指定?
默认的可见性被称为“私有包”(虽然你不能明确地使用它),这意味着该域可以从该类所属的同一个包中访问。
正如mdma所指出的那样,接口成员不是这样,默认是“public”。
请参阅Java的访问说明符
默认说明符取决于上下文。
对于类和接口声明,默认是包私有的。 这是保护和私人之间,只允许在同一包访问类。 (受保护是这样的,但也允许访问包之外的子类)。
class MyClass // package private { int field; // package private field void calc() { // package private method } }
对于接口成员(字段和方法),默认访问是公共的。 但请注意,接口声明本身默认为私有包。
interface MyInterface // package private { int field1; // static final public void method1(); // public abstract }
如果我们有这个声明的话
public interface MyInterface2 extends MyInterface { }
使用MyInterface2的类然后可以从超级接口中看到field1和method1,因为它们是公共的,即使它们看不到MyInterface本身的声明。
如果没有给出访问说明符,那么对于类和类成员来说,它是包级访问(对此没有明确的说明符)。 接口方法是隐式公开的。
默认可见性(无关键字)是包 ,这意味着它将可用于位于相同包中的每个类。
有趣的一面是, 保护不限制对子类的可见性,也限制对同一包中的其他类的可见性
这取决于事情是什么。
-
顶级types(即类,枚举,接口和注释types未在另一types中声明)默认情况下是包私有的。 ( JLS§6.6.1 )
-
在类中,默认情况下,所有成员(即字段,方法和嵌套types声明)和构造函数都是包私有的。 ( JLS§6.6.1 )
- 当一个类没有显式声明的构造函数时,编译器插入一个默认的零参数构造函数,它具有与该类相同的访问说明符 。 ( JLS§8.8.9 )默认的构造函数通常是错误的,因为它总是公开的,但在极less数情况下 ,这是不相同的。
-
在枚举中,构造函数默认是私有的。 事实上,枚举构造器必须是私有的,将它们指定为公共或受保护是错误的。 枚举常量总是公开的 ,不允许任何访问说明符。 枚举的其他成员默认情况下是包私有的。 ( JLS§8.9 )
-
在接口和注解types中,默认情况下,所有成员(也就是说,字段,方法和嵌套types声明)都是公共的。 事实上,接口和注解types的成员必须是公共的,将它们指定为私有或受保护是错误的。 ( JLS§9.3至9.5 )
-
本地类是在方法,构造函数或初始化块内声明的命名类。 它们的作用域是声明它们的
{
..}
块,并且不允许任何访问说明符。 ( JLS第14.3节 )使用reflection,你可以从其他地方实例化本地类,它们是包私有的 ,尽pipe我不确定这个细节是否在JLS中。 -
匿名类是用
new
创build的自定义类,它直接在expression式中指定类体。 ( JLS第15.9.5节 )它们的语法不允许任何访问说明符。 使用reflection,你可以从其他地方实例化匿名类,他们和他们生成的构造函数都是包私有的 ,尽pipe我不确定这个细节是否在JLS中。 -
实例和静态初始化块在语言级没有访问说明符( JLS§8.6和8.7 ),但是静态初始化块被实现为一个名为
<clinit>
( JVMS§2.9 )的方法,所以这个方法必须在内部有一些访问说明符。 我使用hex编辑器检查了由javac编译的类以及Eclipse的编译器,发现这两种方法都生成了package-private方法。 然而,你不能在语言中调用<clinit>()
,因为<
和>
字符在方法名中是无效的,并且reflection方法被硬连接来拒绝它的存在,因此有效的访问说明符是不可访问的 。 该方法只能在类初始化期间由VM调用。 实例初始化块不作为单独的方法编译; 他们的代码被复制到每个构造函数中,所以它们不能被单独访问,即使通过reflection也是如此。
在这里看到更多的细节。 默认不是私有/公共/受保护的,而是完全不同的访问规范。 它没有广泛使用,我更喜欢在我的访问定义更具体。
默认访问说明符是包。类可以访问同一包中的其他类的成员。但是在包外部,它显示为私有
以下是对Java创build者James Gosling的采访中关于包级可见性的引用:
Bill Venners :Java有四个访问级别。 默认是包。 我一直想知道,如果使得包访问默认是方便的,因为C ++人员已经知道的三个关键字是私有的,受保护的和公共的。 或者,如果您有某种特殊的原因,您觉得软件包访问应该是默认的。
詹姆斯·高斯林(James Gosling) :一个包通常是一组写在一起的东西。 所以一般来说,我可以做两件事之一。 一个是你总是把一个关键字给你的域名。 或者我可以有一个默认值。 那么问题是,什么是明智的默认? 我倾向于去做那些最不危险的事情。
所以公众将是一个非常糟糕的事情,使默认。 如果仅仅因为人们实际上不会经常编写私有方法,那么私有可能是一个坏事。 同样的东西与保护。 在看了一堆代码之后,我决定把最安全的东西放在包里。 而C ++没有关键字,因为他们没有包的概念。
但我喜欢它,而不是朋友的概念,因为和朋友一起,你必须列举你所有的朋友是谁,所以如果你给一个包添加一个新的类,那么你通常最终必须去所有的然后更新他们的朋友,我一直认为这是一个完全的痛苦。
但是朋友列表本身导致了某种版本问题。 所以有这样一个友好的阶级的概念。 而我所做的这个默认的好东西 – 我会解决这个问题,那么关键字应该是什么?
有一段时间实际上是一个友好的关键字。 但是因为所有的人都以“P”开始,所以“PH”是“友好的”。 但那只是在那里可能一天。
更新Java 8 default
关键字的用法:许多人已经注意到默认的可见性(没有关键字)
该字段将从该类所属的相同包中被访问。
不要与新的Java 8function( 默认方法 )混淆,该function允许接口在使用default
关键字标记时提供实现。
请参阅: 访问修饰符
在JAVA中有一个名为“default”的访问修饰符,它只允许在该包内直接创build实体。
这是一个有用的链接:
Java访问修饰符/说明符
首先让我说一件事情,在java中没有“访问说明符”这样的术语。 我们应该把所有东西都称为“修饰符”。 因为我们知道final,static,synchronized,volatile ….被称为修饰符,即使Public,private,protected,default,abstract也应该被称为修饰符。 默认是这样一个修饰符,其物理存在不存在,但没有放置修饰符,那么它应该被视为默认修饰符。
为了certificate这一点,举一个例子:
public class Simple{ public static void main(String args[]){ System.out.println("Hello Java"); } }
输出将是: Hello Java
现在把public改为private,看看你得到了什么样的编译器错误:它说“这里不允许使用modifier private”有人可能会出错或者某个教程可能是错误的,但是编译器不会错。 所以我们可以说在java中没有任何术语访问说明符,一切都是修饰符。