Java 中的默认访问说明符是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3530065/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 01:35:01  来源:igfitidea点击:

What is the default access specifier in Java?

javaaccess-specifier

提问by bennedich

I just started reading a Java book and wondered; which access specifier is the default one, if none is specified?

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

采纳答案by KeatsPeeks

The default visibility is known as “package-private” (though you can't use this explicitly), which means the field will be accessible from inside the same package to which the class belongs.

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

As mdma pointed out, it isn't true for interface members though, for which the default is "public".

正如 mdma 指出的那样,对于接口成员来说并非如此,默认为“公共”。

See Java's Access Specifiers

请参阅Java 的访问说明符

回答by Michael Borgwardt

If no access specifier is given, it's package-level access (there is no explicit specifier for this) for classes and class members. Interface methods are implicitly public.

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

回答by Brian Agnew

See herefor more details. The default is none of private/public/protected, but a completely different access specification. It's not widely used, and I prefer to be much more specific in my access definitions.

请参阅此处了解更多详情。默认值不是私有/公共/受保护,而是完全不同的访问规范。它没有被广泛使用,我更喜欢在我的访问定义中更加具体。

回答by Johannes Wachter

The default visibility (no keyword) is packagewhich means that it will be available to every class that is located in the same package.

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

Interesting side note is that protecteddoesn't limit visibility to the subclasses but also to the other classes in the same package

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

回答by mdma

The default specifier depends upon context.

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

For classes, and interface declarations, the default is package private. This falls between protected and private, allowing only classes in the same package access. (protected is like this, but also allowing access to subclasses outside of the package.)

对于类和接口声明,默认是包私有的。这介于受保护和私有之间,只允许同一包中的类访问。(protected 就是这样,但也允许访问包外的子类。)

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

   void calc() {  // package private method

   }
}

For interface members (fields and methods), the default access is public. But note that the interface declaration itself defaults to package private.

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

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

   void method1();     // public abstract
}

If we then have the declaration

如果我们有声明

public interface MyInterface2 extends MyInterface
{

}

Classes using MyInterface2 can then see field1 and method1 from the super interface, because they are public, even though they cannot see the declaration of MyInterface itself.

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

回答by abhi

the default access specifier is package.Classes can access the members of other classes in the same package.but outside the package it appears as private

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

回答by Boann

It depends on what the thing is.

这取决于事情是什么。

  • Top-level types (that is, classes, enums, interfaces, and annotation types not declared inside another type) are package-privateby default. (JLS §6.6.1)

  • In classes, all members (that means fields, methods, and nested type declarations) and constructors are package-privateby default. (JLS §6.6.1)

    • When a class has no explicitly declared constructor, the compiler inserts a default zero-argument constructor which has the same access specifier as the class. (JLS §8.8.9) The default constructor is commonly misstated as always being public, but in rare casesthat's not equivalent.
  • In enums, constructors are privateby default. Indeed, enum contructors mustbe private, and it is an error to specify them as public or protected. Enum constants are always public, and do not permit any access specifier. Other members of enums are package-privateby default. (JLS §8.9)

  • In interfaces and annotation types, all members (again, that means fields, methods, and nested type declarations) are publicby default. Indeed, members of interfaces and annotation types mustbe public, and it is an error to specify them as private or protected. (JLS §9.3 to 9.5)

  • Local classes are named classes declared inside a method, constructor, or initializer block. They are scoped to the {..}block in which they are declaredand do not permit any access specifier. (JLS §14.3) Using reflection, you can instantiate local classes from elsewhere, and they are package-private, although I'm not sure if that detail is in the JLS.

  • Anonymous classes are custom classes created with newwhich specify a class body directly in the expression. (JLS §15.9.5) Their syntax does not permit any access specifier. Using reflection, you can instantiate anonymous classes from elsewhere, and both they and their generated constructors are are package-private, although I'm not sure if that detail is in the JLS.

  • Instance and static initializer blocks do not have access specifiers at the language level (JLS §8.6 & 8.7), but static initializer blocks are implemented as a method named <clinit>(JVMS §2.9), so the method must, internally, have some access specifier. I examined classes compiled by javac and by Eclipse's compiler using a hex editor and found that both generate the method as package-private. However, you can't call <clinit>()within the language because the <and >characters are invalid in a method name, and the reflection methods are hardwired to deny its existence, so effectively its access specifier is no access. The method can only be called by the VM, during class initialization. Instanceinitializer blocks are not compiled as separate methods; their code is copied into each constructor, so they can't be accessed individually, even by reflection.

  • 默认情况下,顶级类型(即未在其他类型中声明的类、枚举、接口和注释类型)是包私有的。( JLS §6.6.1)

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

    • 当一个类没有显式声明的构造函数时,编译器会插入一个默认的零参数构造函数,它与 class具有相同的访问说明符。( JLS §8.8.9) 默认构造函数通常被误认为总是公开的,但在极少数情况下,这并不等效。
  • 在枚举中,构造函数默认是私有的。确实,枚举构造器必须是私有的,将它们指定为公共或受保护是错误的。枚举常量始终是public,并且不允许任何访问说明符。枚举的其他成员默认是包私有的。( JLS §8.9)

  • 在接口和注解类型中,所有成员(同样,这意味着字段、方法和嵌套类型声明)默认都是公共的。实际上,接口和注解类型的成员必须是公共的,将它们指定为私有或受保护是错误的。( JLS §9.3 到 9.5)

  • 局部类是在方法、构造函数或初始化块中声明的命名类。它们的范围仅限于声明它们的{..}块,并且不允许任何访问说明符。( JLS §14.3) 使用反射,您可以从其他地方实例化本地类,它们是package-private,尽管我不确定 JLS 中是否包含该细节。

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

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

回答by Vitalii Fedorenko

Here is a quote about package level visibility from an interview with James Gosling, the creator of Java:

以下是对 Java 的创造者 James Gosling 的采访中关于包级别可见性的引用:

Bill Venners: Java has four access levels. The default is package. I have always wondered if making package access default was convenient because the three keywords that people from C++ already knew about were private, protected, and public. Or if you had some particular reason that you felt package access should be the default.

James Gosling: A package is generally a set of things that are kind of written together. So generically I could have done one of two things. One was force you always to put in a keyword that gives you the domain. Or I could have had a default value. And then the question is, what makes a sensible default? And I tend to go for what is the least dangerous thing.

So public would have been a really bad thing to make the default. Private would probably have been a bad thing to make a default, if only because people actually don't write private methods that often. And same thing with protected. And in looking at a bunch of code that I had, I decided that the most common thing that was reasonably safe was in the package. And C++ didn't have a keyword for that, because they didn't have a notion of packages.

But I liked it rather than the friends notion, because with friends you kind of have to enumerate who all of your friends are, and so if you add a new class to a package, then you generally end up having to go to all of the classes in that package and update their friends, which I had always found to be a complete pain in the butt.

But the friends list itself causes sort of a versioning problem. And so there was this notion of a friendly class. And the nice thing that I was making that the default -- I'll solve the problem so what should the keyword be?

For a while there actually was a friendly keyword. But because all the others start with "P," it was "phriendly" with a "PH." But that was only in there for maybe a day.

Bill Venners:Java 有四个访问级别。默认是包。我一直想知道将包访问设为默认是否方便,因为来自 C++ 的人已经知道的三个关键字是 private、protected 和 public。或者,如果您有某些特殊原因认为包访问应该是默认设置。

James Gosling:一个包通常是一组写在一起的东西。所以一般来说,我可以做两件事之一。一种是强迫您总是输入一个关键字来为您提供域。或者我可以有一个默认值。然后问题是,什么是合理的默认值?我倾向于做最不危险的事情。

因此,将默认设置设为公开将是一件非常糟糕的事情。如果只是因为人们实际上并不经常编写私有方法,那么将其设为默认值可能是一件坏事。和受保护的一样。在查看我拥有的一堆代码时,我决定合理安全的最常见的东西是在包中。而 C++ 没有一个关键字,因为他们没有包的概念。

但我更喜欢它而不是朋友的概念,因为对于朋友,你必须列举出你所有的朋友是谁,所以如果你在一个包中添加一个新类,那么你通常最终不得不去所有的该包中的课程并更新他们的朋友,我一直发现这完全是一件痛苦的事情。

但是朋友列表本身会导致某种版本控制问题。于是就有了友好班级的概念。我把它设为默认值是一件好事——我会解决这个问题,那么关键字应该是什么?

有一段时间实际上有一个友好的关键字。但是因为所有其他人都以“P”开头,所以“PH”是“友好的”。但这只是在那里呆了一天。

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

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

回答by Ahmad Sanie

Update Java 8usage of defaultkeyword: As many others have noted The default visibility (no keyword)

更新Java 8default关键字的用法:正如许多其他人所指出的那样 默认可见性(无关键字)

the field will be accessible from inside the same package to which the class belongs.

该字段可以从类所属的同一个包内部访问。

Not to be confused with the new Java 8feature (Default Methods) that allows an interface to provide an implementation when its labeled with the defaultkeyword.

不要与新的Java 8特性(默认方法)混淆,该特性允许接口在用default关键字标记时提供实现。

See: Access modifiers

请参阅:访问修饰符

回答by Sagar Raut

First of all let me say one thing there is no such term as "Access specifier" in java. We should call everything as "Modifiers". As we know that final, static, synchronised, volatile.... are called as modifiers, even Public, private, protected, default, abstract should also be called as modifiers . Default is such a modifiers where physical existence is not there but no modifiers is placed then it should be treated as default modifiers.

首先让我说一件事,java中没有“访问说明符”这样的术语。我们应该称一切为“修饰符”。正如我们所知,final、static、synchronised、volatile.... 被称为修饰符,甚至 Public、private、protected、default、abstract 也应该被称为修饰符。默认是这样一种修饰符,其中物理存在不存在但未放置修饰符,则应将其视为默认修饰符。

To justify this take one example:

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

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

Output will be: Hello Java

输出将是: Hello Java

Now change public to private and see what compiler error you get: It says "Modifier private is not allowed here" What conclusion is someone can be wrong or some tutorial can be wrong but compiler cannot be wrong. So we can say there is no term access specifier in java everything is modifiers.

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