java Java中可见性修饰符的使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16727414/
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
The use of visibility modifiers in Java
提问by joy
class Orange{
Orange(){
}
}
What is the difference between the usage of the modifier - in this case, package-private - in front of the class and in front of the constructor? I think the modifier in front of the constructor means it is allowed to instantiate an instance of the class Orange
. But what about the modifier in front of the class?
在类前面和在构造函数前面使用修饰符(在本例中为 package-private)有什么区别?我认为构造函数前面的修饰符意味着允许实例化类的实例Orange
。但是类前面的修饰符呢?
回答by Rishikesh Dhokare
To start with there are 4 access levels created by 3 access modifiers.
首先,有 4 个访问级别由 3 个访问修饰符创建。
- public - accessible everywhere
- protected - accessible in the same package and in the children
- default - accessible only in the same package
- private - accessible only in the same class.
- 公共 - 随处可见
- 受保护 - 可在同一个包裹和儿童中访问
- 默认 - 只能在同一个包中访问
- private - 只能在同一个类中访问。
You are correct about - Modifiers at the level of constructors are directly related to the instantiation of the class.
您是正确的 - 构造函数级别的修饰符与类的实例化直接相关。
Modifiers at the level of Class decide the accessibility of the Class.
类级别的修饰符决定了类的可访问性。
回答by Makoto
First, to assuage any fears, the code you've provided isperfectly valid Java syntax.
首先,为了消除任何顾虑,您提供的代码是完全有效的 Java 语法。
In effect, you've created a class that can only be instantiated/used by other classes in the default package. It would also work if you defined it in a package (e.g. package foo;
) since only the classes in package foo
could see this class).
实际上,您创建了一个只能由默认包中的其他类实例化/使用的类。如果您在包中定义它(例如package foo;
),它也可以工作,因为只有包中的类foo
才能看到这个类)。
Now, to the crux of the question.
现在,问题的关键。
There are different ways to control access to fields and members. and they each do different things.
有多种方法可以控制对字段和成员的访问。他们每个人都做不同的事情。
private
visibility is the least visible. Only the defining class can access the field.No modifier, or
package private
is the second least visible. The defining class andall classes within the package may access the field, but subclasses and the rest of the world cannot.protected
is the second most visible. Only other classes are prohibited from accessing the field.public
is the most visible. Everythingcan access the field.
private
可见性是最不可见的。只有定义类可以访问该字段。没有修饰符,或者
package private
是第二个最不可见的。包中的定义类和所有类可以访问该字段,但子类和世界其他地方不能。protected
是第二个最明显的。只有其他类被禁止访问该字段。public
是最明显的。 一切都可以访问该领域。
Modifiers at the level of the class get interesting. This comes from the Java Language Specification, §8.1.1:
类级别的修饰符变得有趣。这来自Java 语言规范第 8.1.1 节:
The access modifier
public
(§6.6) pertains only to top level classes (§7.6) and to member classes (§8.5), not to local classes (§14.3) or anonymous classes (§15.9.5).The access modifiers
protected
andprivate
(§6.6) pertain only to member classes within a directly enclosing class or enum declaration (§8.5).The modifier static pertains only to member classes (§8.5.1), not to top level or local or anonymous classes.
It is a compile-time error if the same modifier appears more than once in a class declaration.
If two or more (distinct) class modifiers appear in a class declaration, then it is customary, though not required, that they appear in the order consistent with that shown above in the production for
ClassModifier
.
访问修饰符
public
(第 6.6 节)仅适用于顶级类(第 7.6 节)和成员类(第 8.5 节),而不适用于本地类(第 14.3 节)或匿名类(第 15.9.5 节)。访问修饰符
protected
和private
(第 6.6 节)仅适用于直接封闭类或枚举声明(第 8.5 节)中的成员类。修饰符 static 仅适用于成员类(第 8.5.1 节),而不适用于顶级或本地或匿名类。
如果相同的修饰符在类声明中多次出现,则是编译时错误。
如果两个或多个(不同的)类修饰符出现在一个类声明中,那么习惯上(尽管不是必需的)它们的出现顺序与上面 的产生式中所示的顺序一致
ClassModifier
。
In general, a class declaration appears something like this:
一般来说,类声明看起来像这样:
ClassDeclaration:
NormalClassDeclaration
EnumDeclaration
NormalClassDeclaration:
ClassModifiers(opt) class Identifier TypeParameters(opt)
Super(opt) Interfaces(opt) ClassBody
Anything with (opt) is considered optional.
任何带有 (opt) 的东西都被认为是可选的。
So, what does this pare down to?
那么,这意味着什么呢?
- The JLS mandates that a class does not need a [class] modifier.
- The JLS mandates that, if a [class] modifier is present, then it follows one of these rules:
- If the modifier is
public
, then it is only applicable to top level classes and member classes. - If the modifier is
protected
orprivate
, then it is only applicable to member classes within a directly enclosing class or enumeration. - The
static
modifier may appear, but is only applicable to member classes.
- If the modifier is
- JLS 要求类不需要 [class] 修饰符。
- JLS 规定,如果存在 [class] 修饰符,则它遵循以下规则之一:
- 如果修饰符是
public
,那么它只适用于顶级类和成员类。 - 如果修饰符是
protected
或private
,则它仅适用于直接封闭类或枚举中的成员类。 - 该
static
修改可能会出现,但只适用于成员类。
- 如果修饰符是
Constructors have a similar rule set.
ConstructorDeclaration:
ConstructorModifiers(opt) ConstructorDeclarator
Throws(opt) ConstructorBody
ConstructorDeclarator:
TypeParameters(opt) SimpleTypeName ( FormalParameterList(opt) )
Again, this breaks down to:
再次,这分解为:
- The JLS mandates that a constructor does not need a [constructor] modifier.
- The JLS mandates that a constructor modifier cannot contain
abstract
,static
,final
,native
,strictfp
, orsynchronized
. - The JLS mandates, if no access modifier is specified for the constructor of a normal class, the constructor has defaultaccess (§8.8.3, emphasis mine).
- JLS 要求构造函数不需要 [constructor] 修饰符。
- 该JLS的任务,一个构造函数修饰符不能含有
abstract
,static
,final
,native
,strictfp
,或synchronized
。 - JLS 规定,如果没有为普通类的构造函数指定访问修饰符,则构造函数具有默认访问权限(第 8.8.3 节,重点是我的)。
回答by Freak
You can only declare a public or default class (in case of top level classes only) in Java and these modifiers decide the accessiblity of the class.
您只能在 Java 中声明公共或默认类(仅在顶级类的情况下),这些修饰符决定了类的可访问性。
I also suggest you to see "Why can't a class or an interface receive private or protected access modifiers?"
我还建议您查看“为什么类或接口不能接收私有或受保护的访问修饰符?”
Now as for as constructor concerns, a constructor will have aaccess-control of type default when no access-modifier is defined explicitly. So this constructor will have a Package Level Access. Only those class which are defined within that package as that of the class with this default constructor will be able to access it. See "Aren't Java constructors public by default?"
现在就构造函数而言,当没有显式定义访问修饰符时,构造函数将具有类型为 default 的访问控制。因此,此构造函数将具有包级别访问权限。只有在该包中定义为具有此默认构造函数的类的类才能访问它。请参阅“默认情况下 Java 构造函数不是公开的吗?”
If the constructor is made private, then only the code within that class can access this. For a better understanding of modifiers, you need to see "Access Modifiers In Java"
如果构造函数是私有的,那么只有该类中的代码才能访问它。为了更好地理解修饰符,您需要查看“ Java 中的访问修饰符”
回答by AlexR
Modifier of class defines who can access the class. For example public
class can be accessed by classes from any package, if no modifier is written the class can be accessed by classes from the samepackage only.
类修饰符定义了谁可以访问该类。例如public
,任何包中的类都可以访问类,如果没有编写修饰符,则该类只能被同一包中的类访问。
Modifier of constructor, method and field has the same meaning. However private
and protected
have more sense. Private can be accessed from the current class only. Protected from its subclasses as far as from just classes from the same package.
构造函数、方法和字段的修饰符具有相同的含义。然而private
,protected
有更多的意义。Private 只能从当前类访问。不受其子类的保护,而不仅仅是来自同一包的类。
Concerning to your question about constructor. Class can have several constructors. Some of them can be private, some other public. You are right that there is no sense to make constructor public if class is package protected: no-one outside package can call this class anyway.
关于你关于构造函数的问题。类可以有多个构造函数。其中一些可以是私人的,一些其他的可以是公共的。你是对的,如果类是包保护的,那么将构造函数设为公开是没有意义的:无论如何,包之外的人都不能调用这个类。
This is exactly like writing public constructors for abstract classes. Since abstract class cannot be instantiated itself its constructors should be protected
or private
although compiler does not care about this.
这就像为抽象类编写公共构造函数一样。由于抽象类本身不能实例化,它的构造函数应该是protected
或者private
尽管编译器不关心这一点。
BTW using default package is not commonly used and not recommended technique.
顺便说一句,使用默认包的方法并不常用,也不推荐使用。
回答by Ravi Trivedi
The useand typesof class
level modifiers:
在使用和类型的class
水平修饰符:
http://javapapers.com/core-java/access-modifiers-in-java-explain/
http://javapapers.com/core-java/access-modifiers-in-java-explain/
The useand typesof constructor
level modifiers:
在使用和类型的constructor
水平修饰符:
http://www.careercup.com/question?id=296844#commentThread302715
http://www.careercup.com/question?id=296844#commentThread302715
回答by Hariprasath
Access Modifiers:
访问修饰符:
- Public - {Can access anywhere in the project}
- Private - {Can access only inside the class}
- Protected - {Can access within the package and sub classes}
- Default - {can access within the package}
- 公共 - {可以在项目中的任何地方访问}
- 私人 - {只能在课堂内访问}
- 受保护 - {可以在包和子类中访问}
- 默认 - {可以在包内访问}
Non-Access Modifiers:
非访问修饰符:
- Static - {for creating class variable and method}
- Final - {for creating finalized variable and method}
- Abstract - {for creating abstract method and class}
- Synchronized - {for threads}
- 静态 - {用于创建类变量和方法}
- Final - {用于创建最终变量和方法}
- Abstract - {用于创建抽象方法和类}
- 同步 - {用于线程}
Some brief discussion on the above modifiers in this link. Refer it for the better understanding.
在此链接中对上述修饰符进行了一些简要讨论。参考它以便更好地理解。
回答by PHZ.fi-Pharazon
I find the best visibility level in Java to be the default
visibility i.e. packagevisibility, because it enables unit test classes to access all the methods, if the test is placed in the same package as the main class.
我发现 Java 中最好的可见性级别是default
可见性,即包可见性,因为它使单元测试类能够访问所有方法,如果测试与主类放在同一个包中。
Also packagevisibility is shorter to write since you can omit the visibility declaration, so there is less boiler plate.
还包能见度较短写的,因为你可以省略知名度声明,所以少锅炉板。
The second best visibility level is protected
, since in some cases you can create your test classes as sub-classes of your main class. However, as stated before, package visibility works better in most cases, if you use packages properly.
第二个最佳可见性级别是protected
,因为在某些情况下,您可以将测试类创建为主类的子类。但是,如前所述,如果您正确使用包,包可见性在大多数情况下效果更好。
Third, typically if you run Sonar and do code review and static analysis on large projects, I have found out that typically 80% of the methods are public
, and 20% are private
/protected
. Thus, the main idea of using private or protected methods is to protect the data/properties from being accessed by bypassing the accessors. Most of the methods will be typically public anyways.
第三,通常如果您运行 Sonar 并对大型项目进行代码和静态分析,我发现通常 80% 的方法是public
,20% 是private
/ protected
。因此,使用私有或受保护方法的主要思想是通过绕过访问器来保护数据/属性不被访问。无论如何,大多数方法通常都是公开的。
The most useless visibility level (but unfortunately commonly used) is private
as it's impossible to test (without using Reflection and modifying the visibility to something else). Also, private
prohibits code re-use in sub-classes, which is the main idea of using object oriented paradigm in the first place, and thus should be avoided. For the same reasons keyword final
should be avoided in most cases.
最无用的可见性级别(但不幸的是常用)是private
因为无法测试(不使用反射并将可见性修改为其他内容)。此外,private
禁止在子类中重用代码,这是首先使用面向对象范式的主要思想,因此应该避免。出于同样的原因,final
在大多数情况下应该避免使用关键字。
Thus, I find your example to be the best practice how to define the visibility levels, except that your constructor is not public :). However, you are missing the package declaration and unit tests.
因此,我发现您的示例是如何定义可见性级别的最佳实践,除了您的构造函数不是公开的 :)。但是,您缺少包声明和单元测试。
回答by Aaron
Class modifiers work similarly to method modifiers. Public, private, final, abstract, etc. work.
类修饰符的工作方式与方法修饰符类似。公共的、私有的、最终的、抽象的等工作。
Public allows the class and its methods to be accessed by classes from any package.
Public 允许任何包中的类访问该类及其方法。
No modifier only allows classes to be access from it's defined package.
没有修饰符只允许从它定义的包访问类。
Private would prevent all access (no point to this if using with a top-level class).
Private 将阻止所有访问(如果与顶级类一起使用,则没有意义)。
Abstract classes allow you to create childclasses derived from the parent(abstract) class. For example, you can make an Abstract Shape class and have a Rectangle class extend shape, inheriting all its methods, variables, and forcing it to define any abstract methods.
抽象类允许你创建子从派生类的父(抽象)类。例如,您可以创建一个 Abstract Shape 类并让一个 Rectangle 类扩展 shape,继承其所有方法、变量,并强制它定义任何抽象方法。