在Java中,在创建类和接口以及处理继承时,是否有明确的规则来确定何时使用每个访问修饰符,即默认的(包私有)、公共的、受保护的和私有的?
当前回答
此图将使您轻松了解public、private、protected和default访问修饰符之间的基本区别。当您没有在代码中声明ant访问修饰符时,默认修饰符会自动发生。
其他回答
它实际上比简单的网格显示要复杂一些。网格告诉是否允许访问,但访问到底由什么构成?此外,访问级别以复杂的方式与嵌套类和继承交互。
“默认”访问(由缺少关键字指定)也称为包专用。异常:在接口中,没有修饰符表示公共访问;禁止公共以外的修饰语。枚举常量始终是公共的。
总结
是否允许使用此访问说明符访问成员?
成员是私有的:仅当成员与调用代码在同一类中定义时。成员是包专用的:仅当调用代码位于成员的直接封装包内时。成员受保护:相同的包,或者如果成员是在包含调用代码的类的超类中定义的。成员公开:是的。
访问说明符应用于什么
局部变量和形式参数不能采用访问说明符。由于根据范围界定规则,外部无法访问它们,因此它们实际上是私有的。
对于顶级作用域中的类,只允许public和package private。这种设计选择大概是因为受保护和私有在包级别是冗余的(没有包的继承)。
所有访问说明符都可以在类成员(构造函数、方法和静态成员函数、嵌套类)上使用。
相关:Java类可访问性
顺序
访问说明符可以严格排序
public>protected>package private>private
这意味着公共提供的访问最多,而私人提供的访问最少。对私有成员的任何引用对包私有成员也是有效的;对包私有成员的任何引用都对受保护成员有效,依此类推。(将受保护成员的访问权限授予同一包中的其他类被认为是错误的。)
笔记
允许类的方法访问同一类的其他对象的私有成员。更准确地说,类C的方法可以访问C的任何子类的对象上的C的私有成员。Java不支持仅通过类而通过实例限制访问。(与Scala相比,Scala确实支持使用private[this]。)您需要访问构造函数来构造对象。因此,如果所有构造函数都是私有的,那么类只能由类中的代码(通常是静态工厂方法或静态变量初始化器)来构造。对于包私有或受保护的构造函数也是如此。只有私有构造函数也意味着类不能在外部子类化,因为Java需要子类的构造函数隐式或显式调用超类构造函数。(但是,它可以包含一个将其子类化的嵌套类。)
内部类
您还必须考虑嵌套范围,例如内部类。复杂性的一个例子是内部类具有成员,这些成员本身可以接受访问修饰符。因此,您可以拥有一个具有公共成员的私有内部类;可以访问该成员吗?(见下文。)一般规则是查看范围并递归地思考,看看是否可以访问每个级别。
然而,这非常复杂,有关详细信息,请参阅Java语言规范。(是的,过去曾出现过编译器错误。)
要了解这些交互的方式,请考虑以下示例。“泄漏”私有内部类是可能的;这通常是一个警告:
class Test {
public static void main(final String ... args) {
System.out.println(Example.leakPrivateClass()); // OK
Example.leakPrivateClass().secretMethod(); // error
}
}
class Example {
private static class NestedClass {
public void secretMethod() {
System.out.println("Hello");
}
}
public static NestedClass leakPrivateClass() {
return new NestedClass();
}
}
编译器输出:
Test.java:4: secretMethod() in Example.NestedClass is defined in an inaccessible class or interface
Example.leakPrivateClass().secretMethod(); // error
^
1 error
一些相关问题:
包私有类内的Java方法可访问性?
官方教程可能对您有所帮助。
Class | Package | Subclass (same pkg) |
Subclass (diff pkg) |
World | |
---|---|---|---|---|---|
public |
+ | + | + | + | + |
protected |
+ | + | + | + | |
no modifier | + | + | + | ||
private |
+ |
+:可访问空白:不可访问
Java访问修改
访问修饰符可适用于类、字段[About]和方法。尝试访问、子类化或重写此。
通过类访问字段或方法。继承与开闭原理〔关于〕后继类(子类)访问修饰符可以是任意的。后继方法(重写)访问修饰符应相同或展开
顶级类(一级范围)可以是公共的,也可以是默认的。嵌套类[About]可以包含其中任何一个
包未应用于包层次结构
[Swift访问修饰符]
包装可见。默认值。不需要修改器。
仅对类可见(私有)。
对世界(公众)可见。
对包和所有子类可见(受保护)。
变量和方法可以在不调用任何修饰符的情况下声明。默认示例:
String name = "john";
public int age(){
return age;
}
私有访问修饰符-私有:
声明为私有的方法、变量和构造函数只能在声明的类本身内访问。私有访问修饰符是限制性最强的访问级别。类和接口不能是私有的。
如果类中存在公共getter方法,则可以在类外部访问声明为私有的变量。
使用私有修饰符是对象封装自身并向外界隐藏数据的主要方式。
示例:
Public class Details{
private String name;
public void setName(String n){
this.name = n;
}
public String getName(){
return this.name;
}
}
公共访问修饰符-Public:
声明为公共的类、方法、构造函数、接口等可以从任何其他类访问。因此,在公共类中声明的字段、方法和块可以从属于Java世界的任何类访问。
但是,如果我们试图访问的公共类位于不同的包中,那么仍然需要导入公共类。
由于类继承,类的所有公共方法和变量都由其子类继承。
例子:
public void cal(){
}
受保护的访问修饰符-受保护的:
在超类中声明为受保护的变量、方法和构造函数只能由另一个包中的子类或受保护成员类的包中的任何类访问。
受保护的访问修饰符不能应用于类和接口。方法、字段可以声明为受保护,但接口中的方法和字段不能声明为受。
受保护的访问使子类有机会使用helper方法或变量,同时防止非相关类尝试使用它。
class Van{
protected boolean speed(){
}
}
class Car{
boolean speed(){
}
}
公共-可从应用程序中的任何位置访问。默认-可从包访问。protected-可从其他包中的包和子类访问。也private-只能从其类访问。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap