访问控制(Access Controlling)是指对 Java 类或类中成员(包括属性和方法等)的操作进行控制,即限制一个类或一个类中的成员在多大的范围内可以被直接使用,以避免其被滥用。
注意:尽可能地使每个类或者成员不被外界访问。
Java 支持四种访问控制:私有的(private)、包级别私有的(package-private)、受保护的(protected)和公有的(publc)
类仅仅支持包级别私有的(package-private)和公有的(publc)两种访问级别。
如果将类声明为公有的(publc),那么类名和文件名必须保持一致,例如:
public class A { //... }
此时将上面代码必须保存到名为 “A.java” 的源码文件中。
如果将类声明为包级别私有的,那么源文件名称和类名可以不一致,但是不推荐这样做。例如:
package com.hxstrive.user; // 将该类保存到 B.java 源文件中 class Bak { public void show() { System.out.println(System.currentTimeMillis()); } } // 验证访问 show() 方法 package com.hxstrive.user; public class A { public static void main(String[] args) { Bak bak = new Bak(); bak.show(); } }
注意:上面仅仅介绍非内部类的访问权限,内部类将在后续介绍。
如果将一个成员声明成私有的,那么只有在声明该成员的顶层类内部才可以访问这个成员。例如:
A.java:
public class A { // 声明成员 name 为私有的 // private 是关键字 private String name; }
B.java:验证在其他类中,能否访问私有成员?不能
package com.hxstrive.demo1; public class B { public void show() { A a = new A(); a.name = "new value"; // 不能访问 } }
C.java:验证在子类中,能够访问私有成员?不能
package com.hxstrive.demo1; public class C extends A { public String getName() { return name; // 不能访问 } }
D.java:验证在其他包中的类,能否访问私有成员?不能
package com.hxstrive.demo2; import com.hxstrive.demo1.A; public class D { public void show() { A a = new A(); a.name = "new value"; // 不能访问 } }
如果将成员设置为包级别私有的,那么声明该成员的包内部的任何类都可以访问这个成员。从技术上讲,它被称为 “缺省 (default) 访问级别”,如果没有为成员指定访问修饰符,就采用这个访问级别。例如:
A.java:
package com.hxstrive.demo1; public class A { // 声明一个包级别私有成员,即缺省访问级别 String name; }
B.java:验证在同一个包下,不同的类中,能否访问包级别私有的成员?能
package com.hxstrive.demo1; public class B { public void show() { A a = new A(); a.name = "new value"; // 正常访问 } }
C.java:验证在同一个包下,并且继承自它(子类),能否访问包级别私有的成员?能
package com.hxstrive.demo1; public class C extends A { public String getName() { return name; // 正常访问 } }
D.java:验证在非同一个包中,能否访问包级别私有的成员?不能
package com.hxstrive.demo2; import com.hxstrive.demo1.A; public class D { public void show() { A a = new A(); a.name = "new value"; // 不能访问 } }
如果将一个成员声明为受保护的,那么声明该成员的类的子类可以访问这个成员,并且声明该成员的包内部的任何类也可以访问这个成员。例如:
A.java:
package com.hxstrive.demo1; public class A { // 将成员 name 声明为受保护的 protected String name; }
B.java:验证同一个包下,但在不同的类中,是否可以访问受保护的成员?能
package com.hxstrive.demo1; public class B { public void show() { A a = new A(); a.name = "new value"; // 正常访问 } }
C.java:验证子类中是否可以访问父类受保护的成员?能
package com.hxstrive.demo1; public class C extends A { public String getName() { return name; // 正常访问 } }
D.java:验证非同一个包下,是否可以访问受保护的成员?不能
package com.hxstrive.demo2; import com.hxstrive.demo1.A; public class D { public void show() { A a = new A(); a.name = "new value"; // 不能访问 } }
如果将一个成员声明为公有的,在任何地方都可以访问该成员。例如:
A.java
package com.hxstrive.demo1; public class A { // 将成员 name 声明为公有的 public String name; }
B.java:验证同一个包下,但在不同的类中,是否可以访问公共的成员?能
package com.hxstrive.demo1; public class B { public void show() { A a = new A(); a.name = "new value"; // 正常访问 } }
C.java:验证子类中是否可以访问父类公共的成员?能
package com.hxstrive.demo1; public class C extends A { public String getName() { return name; // 正常访问 } }
D.java:验证非同一个包下,是否可以访问公共的成员?能
package com.hxstrive.demo2; import com.hxstrive.demo1.A; public class D { public void show() { A a = new A(); a.name = "new value"; // 正常访问 } }
方法和成员一样,也支持私有的(private)、包级别私有的(package-private)、受保护的(protected)和公有的(publc)四种权限控制,例如:
public class A { // 私有方法 private void demo1() {} // 包级别私有方法,缺省方式 void demo2() {} // 受保护的方法 protected void demo3() {} // 公共方法 public void demo4() {} }