面向对象高级

static 关键字

static 关键字是静态的意思,是Java中的一个修饰符,可以修饰成员方法,成员变量
  被static修饰的成员变量,一般叫做静态变量
  被static修饰的成员方法,一般叫做静态方法
static 修饰的特点
  1.被类的所有对象共享:是判断是否使用静态关键字的条件
  2.随着类的加载而加载,优先于对象存在:对象需要类被加载后,才能创建
  3.可以通过类名调用:也可以通过对象名调用(推荐使用类名调用)

static 关键字的注意事项
  1.静态方法只能访问静态的成员
  2.非静态方法可以访问静态的成员,也可以访问非静态的成员
  3.静态方法中是没有this关键字:this是指当前对象的引用,需要在创建对象后才会存在,静态存在时,对象可能还未被创建。

权限修饰符

继承

概念

让类与类之间产生关系(子父类关系),子类可以直接使用父类中非私有的成员。
继承是面向对象三大特征之一。
可以使得子类具有父类的属性和方法,还可以在子类中重新定义,以及追加属性和方法。

格式

public class 子类名 extends 父类名 { }
范例:public class Zi extends Fu { }
Fu:是父类,也被称为基类、超类
Zi:是子类,也被称为派生类

继承的好处和弊端

继承的好处

提高了代码的复用性
提高了代码的维护性
让类与类之间产生了关系,是多态的前提

继承的弊端

继承是侵入性的
降低了代码的灵活性:继承关系,导致子类必须拥有父类非私有属性和方法,让子类自由的世界中多了些约束
增强了代码的耦合性:代码与代码之间存在关联都可以将其称之为"耦合"。

继承的特点

Java只支持单继承,不支持多继承,但支持多层继承。

super 关键字的用法和 this 关键字的用法相似

this:代表本类对象的引用
super:代表父类存储空间的标识(可以理解为父类对象引用)

this和super的使用分别
成员变量:
this.成员变量 - 访问本类成员变量
super.成员变量 - 访问父类成员变量
成员方法:
this.成员方法 - 访问本类成员方法
super.成员方法 - 访问父类成员方法
构造方法:
this(…) - 访问本类构造方法
super(…) - 访问父类构造方法

继承的成员变量访问特点

在子类方法中访问一个变量
  子类局部范围找
  子类成员范围找
  父类成员范围找
  如果都没有就报错(不考虑父亲的父亲…)
注意:如果子父类中,出现了重名的成员变量,通过就近原则,会优先使用子类的成员变量。
  如果一定要使用父类的,可以通过super关键字,进行区分。

继承中成员方法的访问特点

通过子类对象访问一个方法
  子类成员范围找
  父类成员范围找
  如果都没有就报错(不考虑父亲的父亲…)

方法重写

在继承体系中,子类出现了和父类中一模一样的方法声明(方法名、参数列表、返回值类型)

方法重写的应用场景
  当子类需要父类的功能,而功能主体子类有自己特有内容,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容

方法重写注意事项
  父类中私有方法不能被重写(父类私有成员子类是不能继承的)
  父类非静态方法,子类也必须通过非静态方法进行重写
    注意:父类静态方法不能被重写!如果子类中,也存在一个方法声明一模一样的方法,可以理解为:子类将父类中同名的方法,隐藏了起来,并非是方法重写!
  子类重写父类方法时,访问权限必须大于等于父类(public > 默认 > 私有)

方法重载

在同一个类中,方法名相同,参数列表不同(类型不同或者数量不同),与返回值无关。

方法重载的特点:
1)类型不同或者数量不同重载仅对应方法的定义,与方法的调用无关
2)重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关

继承中构造方法的访问特点

子类中所有的构造方法默认都会访问父类中无参的构造方法
  子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。
    子类初始化之前,一定要先完成父类初始化。
构造方法的第一条语句默认都是:super()
  注意:如果我们编写的类,没有手动指定父类,系统也会自动继承Object (Java继承体系中的最顶层父类)

如果父类中没有空参构造方法,只有带参构造方法,会出现什么现象:子类会报错
解决方案:
方式一:子类通过 super,手动调用父类的带参的构造方法
方式二:子类通过 this 去调用本类的其他构造方法,本类其他构造方法再通过 super 去手动调用父类的带参的构造方法(不推荐)
注意:this(…) super(…) 必须放在构造方法的第一行有效语句,并且二者不能共存。

 1 class Fu {
 2     int age;
 3     // 空参数构造方法
 4     //public Fu(){
 5         //System.out.println("父类空参数构造方法");
 6     //}
 7     // 带参数构造方法
 8     public Fu(int age){
 9         this.age = age;
10     }
11 }
12 
13 class Zi extends Fu {
14 
15     //方式二
16     public Zi(){
17         this(10); // super();
18     }
19 
20     //方式一
21     public Zi(int age){
22         super(age);
23     }
24 }

抽象类

抽象方法:将共性的行为(方法)抽取到父类之后,发现该方法的实现逻辑无法在父类中给出具体明确,该方法就可以定义为抽象方法。
抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类

抽象方法的定义格式:
public abstract 返回值类型 方法名(参数列表);

抽象类的定义格式:
public abstract class 类名{}

抽象类注意事项

抽象类不能实例化(创建对象)
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
可以有构造方法
抽象类的子类
  要么重写抽象类中的所有抽象方法
  要么可以将自己也变成一个抽象类

final关键字

final 关键字是最终的意思,可以修饰(方法,变量,类)

final 修饰的特点

修饰方法:表明该方法是最终方法,不能被重写
修饰变量:表明该变量是常量,不能再次被赋值
  变量是基本类型:final 修饰指的是基本类型的数据值不能发生改变
  变量是引用类型:final 修饰指的是引用类型的地址值不能发生改变,但是地址里面的内容是可以发生改变的
修饰类:表明该类是最终类,不能被继承

final修饰成员变量 初始化时机

方式一:在创建的时候,直接赋值(推荐)
方式二:在构造方法结束之前,完成赋值

 1 class Student{
 2     //方式一
 3     final int a=10;
 4     
 5     //方式二
 6     final int b;
 7     public Student(){
 8         b=10;
 9     }
10 }

代码块

在Java中,使用 { } 括起来的代码被称为代码块

分类

局部代码块

位置:方法中定义
作用:限定变量的生命周期,及早释放,提高内存利用率

 1 package com.test.block.local;
 2 
 3 public class Test {
 4 
 5     public static void main(String[] args) {
 6         {
 7             int a = 10;
 8             System.out.println(a);
 9         }
10 
11        // System.out.println(a);  //报错
12     }
13 }

构造代码块

位置:类中方法外定义
特点:每次构造方法执行的时,都会执行该代码块中的代码,并且在构造方法执行前执行
作用:将多个构造方法中相同的代码,抽取到构造代码块中,提高代码的复用性

 1 public class Test {
 2     public static void main(String[] args) {
 3         Student stu1 = new Student();
 4         Student stu2 = new Student(10);
 5     }
 6 }
 7 
 8 class Student {
 9 
10     {
11         System.out.println("我是构造代码块");
12     }
13 
14     public Student(){
15         System.out.println("空参数构造方法");
16     }
17 
18     public Student(int a){
19         System.out.println("带参数构造方法...........");
20     }
21 }

执行结果:

我是构造代码块
空参数构造方法
我是构造代码块
带参数构造方法...........

静态代码块

位置:类中方法外定义
特点:需要通过static关键字修饰,随着类的加载而加载,并且只执行一次
作用:在类加载的时候做一些数据初始化的操作

 1 public class Test {
 2 
 3     public static void main(String[] args) {
 4         Person p1 = new Person();
 5         Person p2 = new Person(10);
 6     }
 7 }
 8 
 9 class Person {
10     static {
11         System.out.println("我是静态代码块, 我执行了");
12     }
13 
14     public Person(){
15         System.out.println("我是Person类的空参数构造方法");
16     }
17 
18     public Person(int a){
19         System.out.println("我是Person类的带...........参数构造方法");
20     }
21 }

执行结果:

我是静态代码块, 我执行了
我是Person类的空参数构造方法
我是Person类的带...........参数构造方法

 接口

当一个类中的所有方法都是抽象方法的时候,我们就可以将其定义为接口。
接口也是一种引用数据类型,它比抽象类还要抽象

接口的定义和特点

接口用关键字interface来定义
  public interface 接口名 {}
接口不能实例化
接口和类之间是实现关系,通过implements关键字表示
  public class 类名 implements 接口名 {}
接口的子类(实现类)
  要么重写接口中的所有抽象方法
  要么是抽象类

注意:接口和类的实现关系,可以单实现,也可以多实现。
  public class 类名 implements 接口名1 , 接口名2 {}

接口中成员的特点

成员变量:
  只能是常量
  默认修饰符:public static final
构造方法:
  没有
成员方法:(关于接口中的方法,JDK8和JDK9中有一些新特性
  只能是抽象方法
  默认修饰符:public abstract

JDK8版中接口成员的特点

一、JDK8版本后:允许在接口中定义非抽象方法,但是需要使用关键字 default 修饰,这些方法就是默认方法。

  作用:解决接口升级的问题(涉及到了接口大面积更新方法,而不想去修改每一个实现类,就可以将更新的方法,定义为带有方法体的默认方法)

  接口中默认方法的定义格式:
    格式:public default 返回值类型 方法名(参数列表) { }
    范例:public default void show() { }

  接口中默认方法的注意事项:
    1、默认方法不是抽象方法,所以不强制被重写。但是可以被重写,重写的时候去掉default关键字。
    2、public可以省略,default不能省略。
    3、如果实现了多个接口,多个接口中存在相同的方法声明,子类就必须对该方法进行重写。

二、JDK8版本后:接口中允许定义static静态方法

  接口中静态方法的定义格式:
    格式:public static 返回值类型 方法名(参数列表) { }
    范例:public static void show() { }

  接口中静态方法的注意事项:
    1、静态方法只能通过接口名调用,不能通过实现类名或者对象名调用。
    2、public可以省略,static不能省略。

JDK9版中接口成员的特点

接口中私有方法的定义格式:
  格式1:private 返回值类型 方法名(参数列表) { }
  范例1:private void show() { }

  格式2:private static 返回值类型 方法名(参数列表) { }
  范例2:private static void method() { }

接口的使用思路

1、如果发现一个类中所有的方法都是抽象方法,那么就可以将该类,改进为一个接口
2、涉及到了接口大面积更新方法,而不想去修改每一个实现类,就可以将更新的方法,定义为带有方法体的默认方法
3、希望默认方法调用的更加简洁,可以考虑设计为static静态方法。(需要去掉default关键字)
4、默认方法中出现了重复的代码,可以考虑抽取出一个私有方法。(需要去掉default关键字)

类和接口的关系

类和类的关系
  继承关系,只能单继承,但是可以多层继承
类和接口的关系
  实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
接口和接口的关系
  继承关系,可以单继承,也可以多继承

注:
  多个父接口当中的抽象方法如果重复,没关系。
  多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写,[而且带着default关键字]。
父接口A:

1 public interface MyInterfaceA {
2     public abstract void methodA();
3     public abstract void methodCommon();
4     public default void methodDefault() {
5         System.out.printIn("AAA");
6     }
7 }

父接口B:

1 public interface MyInterfaceB {
2     public abstract void methodB();
3     public abstract void methodCommon();
4     public default void methodDefault() {
5         System.out.println("BBB");
6     }
7 }

接口与接口之间是多继承的,继承以上两个父接口:

1 public interface MyInterface extends MyInterfaceA, MyInterfaceB {    //接口与接口之间的多继承
2     public abstract void method();
3     //多个父接口当中的默认方法如果重复,那么子接口必须进行默认方法的覆盖重写
4     @Override
5     public default void methodDefault() {
6     
7     }
8 }

两个父接口A、B的中有抽象方法重复,没有关系。但是默认方法重复,则需要在子接口中重写。
接口实现类,一个类实现多个接口:

 1 public class MyInterfaceImpl implements MyInterface {
 2     @Override
 3     public void method() {
 4     }
 5     @Override
 6     public void methodA() {
 7     }
 8     @Override
 9     public void methodB() {
10     }
11     @Override
12     public void methodCommon() {
13     }
14 }

父接口的抽象方法不在子接口中覆盖重写,在实现类中覆盖重写;父接口中重复的默认方法在子接口中覆盖重写。

多态

多态概述

同一个对象,在不同时刻表现出来的不同形态。

  举例:猫
    我们可以说猫是猫:猫 cat = new 猫();
    我们也可以说猫是动物:动物 animal = new 猫();
    这里猫在不同的时刻表现出来了不同的形态,这就是多态

多态的前提和体现
  有继承/实现关系
  有方法重写
  有父类引用指向子类对象

多态中成员访问特点

构造方法:同继承一样,子类会通过 super 访问父类构造方法
成员变量:编译看左边(父类),执行看左边(父类)
成员方法:编译看左边(父类),执行看右边(子类)

注:为什么成员变量和成员方法的访问不一样呢?
  因为成员方法有重写,而成员变量没有

多态的好处和弊端

多态的好处:提高了程序的扩展性
  具体体现:定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的任意子类对象
多态的弊端:不能使用子类的特有功能

 1 public class TestPolymorpic {
 2     public static void main(String[] args) {
 3         useAnimal(new Dog());
 4         useAnimal(new Cat());
 5     }
 6 
 7     public static void useAnimal(Animal a){  // Animal a = new Dog(); // Animal a = new Cat();
 8         a.eat();
 9         //a.watchHome(); //子类特有的成员内容
10     }
11 }
12 
13 abstract class Animal {
14     public abstract void eat();
15 }
16 
17 class Dog extends Animal {
18     public void eat() {
19         System.out.println("狗吃肉");
20     }
21 
22     public void watchHome(){
23         System.out.println("看家");
24     }
25 }
26 
27 class Cat extends Animal {
28     public void eat() {
29         System.out.println("猫吃鱼");
30     }
31 }

多态中的转型

向上转型
  从子到父
  父类引用指向子类对象
向下转型
  从父到子
  父类引用转为子类对象

 1 public class Test4Polymorpic {
 2     public static void main(String[] args) {
 3         // 1. 向上转型 : 父类引用指向子类对象
 4         Fu f = new Zi();
 5         f.show();
 6         // 多态的弊端: 不能调用子类特有的成员
 7         // f.method();
 8         
 9         // 解决方案(A or B)
10         // A: 直接创建子类对象
11         // B: 向下转型
12 
13         // 2. 向下转型 : 从父类类型, 转换回子类类型
14         Zi z = (Zi) f;
15         z.method();
16     }
17 }
18 
19 class Fu {
20     public void show(){
21         System.out.println("Fu..show...");
22     }
23 }
24 
25 class Zi extends Fu {
26     @Override
27     public void show() {
28         System.out.println("Zi..show...");
29     }
30 
31     public void method(){
32         System.out.println("我是子类特有的方法, method");
33     }
34 }

多态中的转型存在的风险

概述:如果被转的引用类型变量,对应的实际类型和目标类型不是同一种类型,那么在转换的时候就会出现ClassCastException

避免强转出现的问题

关键字 instanceof
使用格式:
  变量名 instanceof 类型
  通俗的理解:判断关键字左边的变量,是否是右边的类型,返回boolean类型结果

 1 public class Test3Polymorpic {
 2     public static void main(String[] args) {
 3         useAnimal(new Dog());
 4         useAnimal(new Cat());
 5     }
 6 
 7     public static void useAnimal(Animal a){  // Animal a = new Dog();
 8                                              // Animal a = new Cat();
 9         a.eat();
10 
11         // 判断a变量记录的类型, 是否是Dog
12         if(a instanceof Dog){
13             Dog dog = (Dog) a;
14             dog.watchHome();
15         }
16 
17 //        Dog dog = (Dog) a;
18 //        dog.watchHome();  // ClassCastException  类型转换异常
19     }
20 }
21 
22 abstract class Animal {
23     public abstract void eat();
24 }
25 
26 class Dog extends Animal {
27     public void eat() {
28         System.out.println("狗吃肉");
29     }
30 
31     public void watchHome(){
32         System.out.println("看家");
33     }
34 }
35 
36 class Cat extends Animal {
37     public void eat() {
38         System.out.println("猫吃鱼");
39     }
40 }

 内部类

在一个类中定义一个类。举例:在一个A类的内部定义一个B类, B类就被称为内部类

内部类的访问特点:
  1、内部类可以直接访问外部类的成员,包括私有
  2、外部类要访问内部类的成员,必须创建对象

成员内部类

按照内部类在类中定义的位置不同,可以分为如下两种形式
  在类的成员位置:成员内部类
  在类的局部位置:局部内部类
成员内部类,外界如何创建对象使用呢?
  格式:外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
  范例:Outer.Inner oi = new Outer().new Inner();

 1 public class Test1Inner {
 2     public static void main(String[] args) {
 3         Outer.Inner i = new Outer().new Inner();
 4         System.out.println(i.num);
 5         i.show();
 6     }
 7 }
 8 
 9 class Outer {
10     private int a = 10;
11 
12     class Inner {
13         int num = 10;
14 
15         public void show(){
16             System.out.println("Inner..show");
17             // 内部类, 访问外部类成员, 可以直接访问, 包括私有
18             System.out.println(a);
19         }
20     }
21 }

成员内部类,也属于(成员),既然是成员就可以被一些修饰符所修饰。
  private
    私有成员内部类访问:在自己所在的外部类中创建对象访问。

 1 public class Test2Innerclass {
 2     public static void main(String[] args) {
 3         Outer o = new Outer();
 4         o.method();
 5     }
 6 }
 7 
 8 class Outer {
 9     private class Inner {
10         public void show(){
11             System.out.println("inner..show");
12         }
13     }
14 
15     public void method(){
16         Inner i = new Inner();
17         i.show();
18     }
19 }

  static
    静态成员内部类访问格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
    静态成员内部类中的静态方法:外部类名.内部类名.方法名();

 1 public class Test3Innerclass {
 2     public static void main(String[] args) {
 3         Outer.Inner oi = new Outer.Inner();
 4         oi.show();
 5 
 6         Outer.Inner.method();
 7     }
 8 }
 9 
10 class Outer {
11     static class Inner {
12         public void show(){
13             System.out.println("inner..show");
14         }
15 
16         public static void method(){
17             System.out.println("inner..method");
18         }
19     }
20 }

局部内部类

局部内部类是在方法中定义的类,所以外界是无法直接使用,需要在方法内部创建对象并使用
该类可以直接访问外部类的成员,也可以访问方法内的局部变量

 1 public class Test4Innerclass {
 2     public static void main(String[] args) {
 3         Outer o = new Outer();
 4         o.method();
 5     }
 6 }
 7 
 8 class Outer {
 9     int a = 10;
10     public void method(){
11         int b = 20;
12 
13         class Inner {
14             public void show(){
15                 System.out.println("show...");
16                 System.out.println(a);
17                 System.out.println(b);
18             }
19         }
20 
21         Inner i = new Inner();
22         i.show();
23     }
24 }

匿名内部类

概述:匿名内部类本质上是一个特殊的局部内部类(定义在方法内部)
前提:需要存在一个接口或类

格式:
  new 类名或者接口名() {
    重写方法;
  };

 1 public class Test5Innerclass {
 2     /*
 3         1. 创建实现类, 通过implements关键字去实现接口
 4         2. 重写方法
 5         3. 创建实现类对象
 6         4. 调用重写后的方法.
 7 
 8         匿名内部类:
 9             前提: 需要存在类\接口
10             格式:
11                     new 类名 \ 接口名 (){
12                         重写方法
13                     }
14      */
15     public static void main(String[] args) {
16         InterImpl ii = new InterImpl();
17         ii.show();
18 
19         // 匿名内部类的理解: 将继承/实现, 方法重写, 创建对象, 放在了一步进行.
20         // 解释: 实现了Inter接口的, 一个实现类对象.
21         new Inter() {
22             @Override
23             public void show() {
24                 System.out.println("我是匿名内部类中的show方法");
25             }
26         }.show();
27 
28         // 情况: 接口中存在多个方法
29         Inter2 i = new Inter2() {
30             @Override
31             public void show1() {
32                 System.out.println("show1...");
33             }
34 
35             @Override
36             public void show2() {
37                 System.out.println("show2...");
38             }
39         };
40 
41         i.show1();
42         i.show2();
43     }
44 }
45 
46 interface Inter {
47     void show();
48 }
49 
50 interface Inter2 {
51     void show1();
52     void show2();
53 }
54 
55 class InterImpl implements Inter {
56     @Override
57     public void show() {
58         System.out.println("InterImpl  重写的show方法");
59     }
60 }

匿名内部类在开发中的使用

当方法的形式参数是接口或者抽象类时,可以将匿名内部类作为实际参数进行传递。

 1 public class TestSwimming {
 2     public static void main(String[] args) {
 3         goSwimming(new Swimming() {
 4             @Override
 5             public void swim() {
 6                 System.out.println("铁汁, 我们去游泳吧");
 7             }
 8         });
 9     }
10 
11     /**
12      * 使用接口的方法
13      */
14     public static void goSwimming(Swimming swimming){
15         /*
16             Swimming swimming = new Swimming() {
17                 @Override
18                 public void swim() {
19                     System.out.println("铁汁, 我们去游泳吧");
20                 }
21             }
22          */
23         swimming.swim();
24     }
25 }
26 
27 //游泳接口
28 interface Swimming {
29     void swim();
30 }

Lambda表达式

函数式编程思想

  面向对象思想强调“必须通过对象的形式来做事情”
  函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做”

Lambda表达式的标准格式

格式:( 形式参数 ) -> { 代码块 }  (组成Lambda表达式的三要素)
  形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
  ->:由英文中画线和大于符号组成,固定写法。代表指向动作
  代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

Lambda表达式的使用前提:
  有一个接口
  接口中有且仅有一个抽象方法

Lambda表达式的省略模式

省略规则:
  参数类型可以省略,但是有多个参数的情况下,不能只省略一个
  如果参数有且仅有一个,那么小括号可以省略
  如果代码块的语句只有一条,可以省略大括号和分号,甚至是return

示例

无参数无返回值

 1 public class TestLambda {
 2     public static void main(String[] args) {
 3         useShowHandler(new ShowHandler() {
 4             @Override
 5             public void show() {
 6                 System.out.println("我是匿名内部类中的show方法");
 7             }
 8         });
 9 
10         // Lambda实现
11         useShowHandler( () -> {System.out.println("我是Lambda中的show方法");} );
12         // Lambda实现-省略模式
13         useShowHandler( () -> System.out.println("我是Lambda中的show方法"));
14     }
15 
16     public static void useShowHandler(ShowHandler showHandler){
17         showHandler.show();
18     }
19 
20 }
21 
22 interface ShowHandler {
23     void show();
24 }

有参数也有返回值

 1 public class CalculatorDemo {
 2     public static void main(String[] args) {
 3         useCalculator(new Calculator() {
 4             @Override
 5             public int calc(int a, int b) {
 6                 return a + b;
 7             }
 8         });
 9         
10         // Lambda实现
11         useCalculator( (int a, int b) -> {
12             return a + b;
13         } );
14         // Lambda实现-省略模式
15         useCalculator( ( a,  b) ->
16              a + b
17          );
18     }
19 
20     public static void useCalculator(Calculator calculator){
21         int result = calculator.calc(10,20);
22         System.out.println(result);
23     }
24 }
25 
26 interface Calculator {
27     int calc(int a, int b);
28 }

 Lambda表达式和匿名内部类的区别

所需类型不同
  匿名内部类:可以是接口,也可以是抽象类,还可以是具体类
  Lambda表达式:只能是接口
使用限制不同
  如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
  如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
实现原理不同
  匿名内部类:编译之后,产生一个单独的.class字节码文件
  Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成

posted @ 2023-03-14 23:50  溯鸣  阅读(16)  评论(0编辑  收藏  举报