- 内部类提供了更精细的封装
- 内部类是和外部类的实例相绑定的
它可以调用外部类的实例方法,包括被private修饰的方法或成员 内部类之所以能访问外部类的成员,是因为编译器帮你的内部类注入了一个this$0
的外部类实例成员
- 外部类也可以调用内部类中被private修饰的方法或成员变量
- 内部类不一定非要定义在类中,也可以定义在接口,枚举中
- 静态内部类不和实例绑定,因此它不能调用外部类的实例方法或成员变量
- 静态内部类只能调用外部类中的静态变量或静态方法 不过还是有办法访问外部类中的非静态方法或成员,就是通过构造器将外部类的实例传进来
- 永远优先使用静态内部类,除非编译报错。 因为编译器偷偷帮你注入的外部类实例可能你用不到,造成浪费空间
- new 一个接口并提供实现体,就相当于创建一个实现该接口的匿名内部类
- new 一个抽象类提供实现体,就相当于创建一个覆盖了对应方法的子类(匿名内部类)
- 匿名内部类可以变为lambda表达式
- 匿名内部类虽然没有名字,但在字节码的表示中是以外围类的名字+$数字来命名的
- 匿名内部类也可以访问外围类中的实例变量或方法(类似其他语言中的闭包的概念)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class Fork {
public static void main(String[] args) {
// 请在这里使用Java代码fork一个子进程,
// 将fork的子进程的标准输出重定向到指定文件:工作目录下名为output.txt的文件
// 工作目录是项目目录下的working-directory目录
//(可以用getWorkingDir()方法得到这个目录对应的File对象)
// 传递的命令是sh run.sh
// 环境变量是AAA=123
ProcessBuilder processBuilder = new ProcessBuilder("bash", "run.sh");
processBuilder.directory(getWorkingDir());
Map<String, String> environment = processBuilder.environment();
environment.put("AAA", "123"); // 设置新进程的环境变量
// processBuilder.inheritIO(); // 将新进程的标准输入/输出全部打印到当前的进程中来
processBuilder.redirectOutput(getOutputFile()); // 将输出重定向到文件
processBuilder.start().waitFor(); // 启动进程并等待其结束
}
private static File getWorkingDir() {
Path projectDir = Paths.get(System.getProperty("user.dir"));
return projectDir.resolve("working-directory").toFile();
}
private static File getOutputFile() {
return new File(getWorkingDir(), "output.txt");
}
}
|
- 普通编译
javac Hello.java
- 编译并指定依赖类去哪里找
javac -classpath commons-lang3-3.9.jar Hello.java
- 向java传递参数
java Hello 1 2 3
- 向java传递系统属性
java -DAA=123 Hello
- 运行并指定依赖类去哪里找
java -classpath commons-lang3-3.9.jar:. Hello