参考资料:
包
package
是 Java 中名字空间,可以用于解决类名冲突,每个类都属于一个包,完整的类名是 包名.类名
。
package ming; // 声明包名ming
public class Person {
}
JVM 只看完整类名。包可以是多层结构,例如 java.util
。
需要注意的是,包没有父子关系,例如
java.util
和java.util.zip
是完全不同的包
需要按照包结构将 Java 文件组织起来,所有 Java 文件的目录层次要与包的层次对应。
package_sample
└─ src
├─ hong
│ └─ Person.java
│ ming
│ └─ Person.java
└─ mr
└─ jun
└─ Arrays.java
包作用域
修饰符 | 类内部 | 同包 | 子类 | 任何地方 |
---|---|---|---|---|
public | Yes | Yes | Yes | Yes |
protected | Yes | Yes | Yes | |
包访问权限 | Yes | Yes | ||
private | Yes |
不用 public
、protected
、private
修饰的字段和方法就是包作用域。
import
编写 class
时,编译器会自动我们 import
包内其他 class
和 java.lang
中的所有类。
如果我们想要在类中使用其他包中的类,有如下写法:
// 法一:写出完整类名
package ming;
public class Person {
public void run() {
// 写完整类名: mr.jun.Arrays
mr.jun.Arrays arrays = new mr.jun.Arrays();
}
}
// 法二:使用import
package ming;
// 导入完整类名:
import mr.jun.Arrays;
// 导入包中所有类
import mr.jun.*
public class Person {
public void run() {
// 写简单类名: Arrays
Arrays arrays = new Arrays();
}
}
// 法三:使用import static,仅适用于导入静态字段和静态方法
// 导入System类的所有静态字段和静态方法:
import static java.lang.System.*;
public class Main {
public static void main(String[] args) {
// 相当于调用System.out.println(…)
out.println("Hello, world!");
}
}
Java 编译器编译出的
.class
文件中均为完整类名,故编译过程中遇到一个简单类名时,按照当前package
、import
的类 、java.lang
的顺序进行查找。
作用域
先访问类,再访问类内的字段或方法。
局部变量的作用域与 C++ 类似。
内部类
Inner Class
定义在一个类内部的类是 Inner Class :
// inner class
public class Main {
public static void main(String[] args) {
Outer outer = new Outer("Nested"); // 实例化一个Outer
// 要实例化一个Inner,必须先创建一个Outer实例,然后再通过这个Outer实例来创建Inner实例
Outer.Inner inner = outer.new Inner(); // 实例化一个Inner
inner.hello();
}
}
class Outer {
private String name;
Outer(String name) {
this.name = name;
}
class Inner {
void hello() {
// Inner实例持有Outer实例,可以通过Outer.this访问该实例
// Inner可以访问Outer的private字段和方法
System.out.println("Hello, " + Outer.this.name);
}
}
}
Anonymous Class
这部分暂时省略,因为不知道有什么用。