Java 中为什么要设计访问权限控制机制呢? 主要作用有两点:

(1) 为了使用户不要触碰那些他们不该触碰的部分,这些部分对于类内部的操作时必要的,但是它并不属于客户端程序员所需接口的一部分。

(2) 为了让类库设计者可用更改类的内部工作方式,而不必担心会对用户造成重大影响。

Java 中的访问权限控制的等级,按照权限从大到小依次为

Public -> protected -> 包访问权限(没有权限修饰词) -> private

(package)

Java 中包 (package) 的概念和 C++ 中命名空间 (namespace) 的概念很类似,都可以限制类的作用域。二者最大的差别在于, Java 中的包隐式地指明了类的树形层级结构(同时也是 Java 源码文件的目录结构)。这样做的好处在于:可以通过文件系统中对于文件路径唯一性的要求来限制类的唯一性。

编写一个 Java 源代码文件 ( .java 文件 ) 时,此文件通常被称为 编译单元 。在编译单元内最多允许有一个 public 类,且该类的名称必须与文件名完全相同(包括大小写)。

编译一个 .java 文件时,在 .java 文件中的每个类都会有一个 .class 输出文件,这个文件名和类名是相同的。 Java 可运行程序是一组可以打包并压缩为一个 Java 文档文件 (JAR 包,使用 Java jar 文档生成器 ) .class 文件。 Java 解释器负责这些文件的查找、装载和解释。

类库实际上是一组类文件。其中每个 .java 文件最多允许有一个 public 类,以及任意数量的非 public 类。因此,每个文件都有一个构件。如果要将这些构件(每个构建有一个 .java 文件和若干个 .class 文件)组织起来,形成不同的群组,可以使用 Java 中的关键字 package

(package) 的作用

(1) 把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。

(2) 如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。

(3) 包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

Java 中,使用 package 关键字来指定代码所属的包(命名空间)。

语法格式:

(1) 包的名字隐含地指出了代码的目录结构。

(2) 同一目录下的 public 类名(同时也是 java 文件名)应该是独一无二的。

(3) 包声明应该在源文件的第一行,每个源文件只能有一个包声明,这个文件中的每个类型都应用于它。

(4) 如果一个源文件中没有使用包声明,那么其中的类,函数,枚举,注释等将被放在一个无名的包( unnamed package )中。

(5) package 的名字一般全是小写字母。

查看 java.util.ArrayList 类的源码可以看到文件第一行代码为:

package :包访问权限

如果不提供任何访问权限修饰词,则意味着它是 包访问权限

默认访问权限 没有任何关键字 ,但通常是指 包访问权限 (有时也表示为 friendly ,有点像 C++ 中的友元概念 )。这意味着包中所有其他类都可以访问这个成员或方法,但是 这个包之外的所有类不可以访问

com.notes.packages.test .Info

package com.notes.packages.test;

public class Info {

void print() { System. out .println( "default method -- print()" ); }

package com.notes.packages.test;

public class PublicDemo01 {

public static void main(String[] args ) {

Info x = new Info();

x .print();

package com.notes.packages;

import com.notes.packages.test.Info;

public class PublicDemo02 {

public static void main(String[] args ) {

Info x = new Info();

// x.print(); // Error

package com.notes.packages.test;

public class Info {

public void print() { System. out .println( "public method -- print()" ); }

protected :继承访问权限

新类(称之子类或派生类)通过继承可以复用一个现有类(称之父类或基类),然后扩展基类的成员、方法。有时,基类的创建者会希望某个特定成员,将它的访问权限赋予派生类而不是所有类。 public 无法做到这一点,为此,引入了 protected 来完成这一工作。 protected 也提供包访问权限,也就是说, 派生类以及相同包内的其他类都可以访问 protected 成员或方法

例:子类继承父类后,可以访问父类的 protected 成员。

private String a = "private" ;

protected String b = "protected" ;

public String c = "public" ;

class Son extends Father {

public void print() {

// System.out.println("element a " + super.a); // Error

System. out .println( "element b " + super . b );

System. out .println( "element c " + super . c );

public class ProtectedDemo01 {

public static void main(String args []) {

Son sub = new Son();

sub .print();

除此之外,还有一些需要注意的点:

(1) 静态成员、静态方法的权限修饰词的用法和普通成员、方法一样。

(2) 类虽然也可以被修饰词修饰,但是不可以用 private protected 两个权限修辞词。

(3) 有些书中将包访问权限又叫做默认访问权限。个人不建议这么去记,因为这很容易与 Java Se8 中新特性 —— default 关键字混淆。这个关键字只能用于 Interface ,作用是 允许程序员在 Interface 中定义接口的默认具体实现 (以往的 JDK 版本是不允许这样的,你只能在接口中声明方法)。