JAVA07-内部类和Fork

什么是内部类

  1. 内部类提供了更精细的封装
  2. 内部类是和外部类的实例相绑定的

它可以调用外部类的实例方法,包括被private修饰的方法或成员 内部类之所以能访问外部类的成员,是因为编译器帮你的内部类注入了一个this$0的外部类实例成员

  1. 外部类也可以调用内部类中被private修饰的方法或成员变量
  2. 内部类不一定非要定义在类中,也可以定义在接口,枚举中

静态内部类

  1. 静态内部类不和实例绑定,因此它不能调用外部类的实例方法或成员变量
  2. 静态内部类只能调用外部类中的静态变量或静态方法 不过还是有办法访问外部类中的非静态方法或成员,就是通过构造器将外部类的实例传进来

什么时候使用内部类,什么时候使用静态内部类?

  1. 永远优先使用静态内部类,除非编译报错。 因为编译器偷偷帮你注入的外部类实例可能你用不到,造成浪费空间

匿名内部类

  1. new 一个接口并提供实现体,就相当于创建一个实现该接口的匿名内部类
  2. new 一个抽象类提供实现体,就相当于创建一个覆盖了对应方法的子类(匿名内部类)
  3. 匿名内部类可以变为lambda表达式
  4. 匿名内部类虽然没有名字,但在字节码的表示中是以外围类的名字+$数字来命名的
  5. 匿名内部类也可以访问外围类中的实例变量或方法(类似其他语言中的闭包的概念)

在Java中Fork子进程

 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");
    }
}

用命令行编译Java程序

  1. 普通编译 javac Hello.java
  2. 编译并指定依赖类去哪里找 javac -classpath commons-lang3-3.9.jar Hello.java
  3. 向java传递参数 java Hello 1 2 3
  4. 向java传递系统属性 java -DAA=123 Hello
  5. 运行并指定依赖类去哪里找 java -classpath commons-lang3-3.9.jar:. Hello
updatedupdated2025-03-012025-03-01