在Java中,在创建类和接口以及处理继承时,是否有明确的规则来确定何时使用每个访问修饰符,即默认的(包私有)、公共的、受保护的和私有的?
当前回答
Java中的访问修饰符。
Java访问修饰符用于在Java中提供访问控制。
1.默认值:
只能访问同一包中的类。
例如
// Saved in file A.java
package pack;
class A{
void msg(){System.out.println("Hello");}
}
// Saved in file B.java
package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A(); // Compile Time Error
obj.msg(); // Compile Time Error
}
}
这种访问比公共访问受到更多的限制和保护,但比私人访问受到更少的限制。
2.公众
可以从任何地方访问。(全球访问)
例如
// Saved in file A.java
package pack;
public class A{
public void msg(){System.out.println("Hello");}
}
// Saved in file B.java
package mypack;
import pack.*;
class B{
public static void main(String args[]){
A obj = new A();
obj.msg();
}
}
输出:您好
3.私人
只能在同一类中访问。
如果您试图访问另一个类中一个类的私有成员,将引发编译错误。例如
class A{
private int data = 40;
private void msg(){System.out.println("Hello java");}
}
public class Simple{
public static void main(String args[]){
A obj = new A();
System.out.println(obj.data); // Compile Time Error
obj.msg(); // Compile Time Error
}
}
4.受保护
只能访问同一包中的类和子类
例如
// Saved in file A.java
package pack;
public class A{
protected void msg(){System.out.println("Hello");}
}
// Saved in file B.java
package mypack;
import pack.*;
class B extends A{
public static void main(String args[]){
B obj = new B();
obj.msg();
}
}
输出:您好
其他回答
Java访问修改
访问修饰符可适用于类、字段[About]和方法。尝试访问、子类化或重写此。
通过类访问字段或方法。继承与开闭原理〔关于〕后继类(子类)访问修饰符可以是任意的。后继方法(重写)访问修饰符应相同或展开
顶级类(一级范围)可以是公共的,也可以是默认的。嵌套类[About]可以包含其中任何一个
包未应用于包层次结构
[Swift访问修饰符]
访问修饰符用于限制多个级别的访问。
公共:它基本上和您可以从任何类访问一样简单,无论它是否在同一个包中。
若要访问同一个包,可以直接访问,但若您在另一个包中,则可以创建类的对象。
默认值:它可以在同一个包中从任何一类包访问。
要访问,可以创建类的对象。但不能在包外访问此变量。
受保护:您可以访问同一包中的变量以及任何其他包中的子类。所以基本上它是默认+继承的行为。
要访问基类中定义的受保护字段,可以创建子类的对象。
私有:可以在同一类中访问。
在非静态方法中,由于该引用(也在构造函数中),您可以直接访问,但要在静态方法中访问,您需要创建类的对象。
公共-可从应用程序中的任何位置访问。默认-可从包访问。protected-可从其他包中的包和子类访问。也private-只能从其类访问。
当谈到访问修饰符时,我们很容易理解,非常简单的规则包括它们。
专用访问修饰符用于:-仅同一类
默认Access修饰符用于:-仅同一类/同一包子类
Protected Access修饰符用于:-同一类/同一包子类/同包非子类/不同包子类
公共访问修饰符用于:-我们可以在任何地方使用(相同的类/相同的包子类/相同包非子类/不同的包子类别/不同包非子类别)
它实际上比简单的网格显示要复杂一些。网格告诉是否允许访问,但访问到底由什么构成?此外,访问级别以复杂的方式与嵌套类和继承交互。
“默认”访问(由缺少关键字指定)也称为包专用。异常:在接口中,没有修饰符表示公共访问;禁止公共以外的修饰语。枚举常量始终是公共的。
总结
是否允许使用此访问说明符访问成员?
成员是私有的:仅当成员与调用代码在同一类中定义时。成员是包专用的:仅当调用代码位于成员的直接封装包内时。成员受保护:相同的包,或者如果成员是在包含调用代码的类的超类中定义的。成员公开:是的。
访问说明符应用于什么
局部变量和形式参数不能采用访问说明符。由于根据范围界定规则,外部无法访问它们,因此它们实际上是私有的。
对于顶级作用域中的类,只允许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方法可访问性?
推荐文章
- 什么时候我们应该使用观察者和可观察对象?
- Java中的split()方法对点(.)不起作用。
- Eclipse调试器总是阻塞在ThreadPoolExecutor上,没有任何明显的异常,为什么?
- Java生成两个给定值之间的随机数
- 如何有效地从数组列表或字符串数组中删除所有空元素?
- 比较JUnit断言中的数组,简洁的内置方式?
- codestyle;把javadoc放在注释之前还是之后?
- 如何在Spring中定义List bean ?
- 将Set<T>转换为List<T>的最简洁的方法
- 在JavaScript中,什么相当于Java的Thread.sleep() ?
- 使用Java重命名文件
- URL从Java中的类路径加载资源
- .toArray(new MyClass[0]) or .toArray(new MyClass[myList.size()])?
- Hibernate中不同的保存方法之间有什么区别?
- Java 8流和数组操作