Java多态分支


在这里插入图片描述

🐧Java多态

🐟多态的引出

public class Animal {
    private String name;

    public Animal(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class Dog extends Animal{
    public Dog(String name) {
        super(name);
    }
}
public class Cat extends Animal{
    public Cat(String name) {
        super(name);
    }
}
public class Food {
    private String name;

    public Food(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class Bone extends Food {
    public Bone(String name) {
        super(name);
    }
}
public class Fish extends Food {
    public Fish(String name) {
        super(name);
    }
}
public class Master {
    private String name;

    public Master(String name) {
        this.name = name;
    }

    //主人给小狗 喂食 骨头
    public void feed(Dog dog, Bone bone) {
        System.out.println("主人 " + name + " 给 " + dog.getName() + " 喂 " + bone.getName());
    }

    //主人给小猫 喂食 黄花鱼
    public void feed(Cat cat, Fish fish) {
        System.out.println("主人 " + name + " 给 " + cat.getName() + " 喂 " + fish.getName());
    }

    //如果动物很多, 食物很多
    //===> feed 方法很多, 不利于管理和维护
    //Pig --> Rice
    //Tiger --> Meat ...
}
public class Poly01 {
    public static void main(String[] args) {
        Master tom = new Master("tom");

        Dog dog = new Dog("旺财");
        Bone bone = new Bone("大棒骨");
        tom.feed(dog, bone);
        System.out.println("======================");
        Cat cat = new Cat("花喵");
        Fish fish = new Fish("大黄鱼");
        tom.feed(cat, fish);
    }
}

🐟方法的多态

〇多态基本介绍

  1. 方法或对象具有多种形态. 是面向对象的第三大特征, 多态是建立在封装和继承之上的.

〇多态的具体体现

  1. 方法的多态 PloyMethod.java - 重写和重载就体现多态
public class polyMethod {
    public static void main(String[] args) {
        //方法重载体现多态
        A a = new A();
        //这里我们传入不同的参数, 就会调用不同的sum方法, 就体现多态
        System.out.println(a.sum(10, 20));
        System.out.println(a.sum(10, 20, 30));

        //方法重写体现多态
        B b = new B();
        a.say();
        b.say();
    }
}
class B { //父类
    public void say() {
        System.out.println("B say()方法被调用...");
    }
}

class A extends B { //子类
    public int sum(int n1, int n2) {//和下面的sum 构成重载
        return n1 + n2;
    }

    public int sum(int n1, int n2, int n3) {
        return n1 + n2 + n3;
    }

    public void say() {
        System.out.println("A say()方法被调用...");
    }
}

🐟对象的多态

(1) 一个对象的编译类型和运行类型可以不一致
(2) 编译类型在定义对象时, 就确定了, 不能改变
(3) 运行类型是可以改变的
(4) 编译类型看定义时 = 号 的左边, 运行类型看 = 号的 右边

Animal animal = new Dog(); [animal 编译类型是Animal, 运行类型是Dog]
animal = new Cat(); [animal 的运行类型变成了Cat, 编译类型仍然是 Animal]

public class Animal {
    public void cry() {
        System.out.println("Animal cry() Animal在叫...");
    }
}
public class Cat extends Animal {
    public void cry() {
        System.out.println("Cat cry() 小猫喵喵叫...");
    }
}
public class Dog extends Animal {
    public void cry() {
        System.out.println("Dog cry() 小狗汪汪叫...");
    }
}
public class PolyObject {
    public static void main(String[] args) {
        //体验对象多态的特点

        //animal编译类型是Animal, 运行类型是Dog
        Animal animal = new Dog();
        //因为运行时, 这时即执行到该行时, animal的运行类型是Dog, 所以这个cry就是Dog的cry
        animal.cry();//小狗汪汪叫...

        //animal 编译类型是 Animal, 运行类型是 Cat
        animal = new Cat();
        animal.cry();//小猫喵喵叫...
    }
}

🐟快速入门

改善主人喂食 食物的问题

//使用多态机制, 可以统一地管理主人喂食 食物的问题
//animal 编译类型是Animal, 它可以接收(指向) Animal子类的对象
//food 编译类型是Food, 它可以指向 Food子类的对象
public void feed(Animal animal, Food food) {
    System.out.println("主人 " + name + " 给 " + animal.getName() + " 喂 " + food.getName());
}

测试

public class Poly01 {
    public static void main(String[] args) {
        Master tom = new Master("tom");
       
        //添加给小猪 喂 米饭
        System.out.println("======================");
        Pig pig = new Pig("佩奇~");
        Rice rice = new Rice("米饭~");
        tom.feed(pig, rice);
    }
}

🐟注意事项和细节

com.zzw.poly_.detail_包: PolyDetail.java

多态的前提

两个对象(类)存在继承关系

多态的向上转型

1)本质: 父类的引用指向了子类的对象
2)语法特点: 父类引用 引用名 = new 子类类型();
3)特点: 编译类型看左边, 运行类型看右边
可以调用父类中的所有成员(需要遵守访问权限)
不能调用子类中特有成员
最终运行效果看子类(运行类型)的具体实现

public class Animal {
    String name = "动物";
    int age = 10;

    public void sleep() {
        System.out.println("睡");
    }

    public void run() {
        System.out.println("跑");
    }

    public void eat() {
        System.out.println("吃");
    }

    public void show() {
        System.out.println("hello, 你好");
    }
}
public class Cat extends Animal {
    public void eat() {//方法重写
        System.out.println("猫吃鱼");
    }

    public void catchMouse() {//Cat特有的方法
        System.out.println("猫抓老鼠");
    }
}
public class PoyDetail {
    public static void main(String[] args) {
        //向上转型: 父类的引用指向了之类的对象
        //语法: 父类类型 引用名 = new 子类类型();
        Animal animal = new Cat();
        Object obj = new Cat();//可以吗? 可以 Object 也是 Cat的父类

        //向上转型调用方法的规则如下:
        //(1)可以调用父类中的所有成员(需要遵守访问权限)
        //(2)但是不能调用子类的特有的成员
        //(3)因为在编译阶段, 能调用哪些成员, 是由编译类型来决定的
        //animal.catchMouse();错误
        //(4)最终的运行效果看子类(运行类型)的具体实现
        animal.eat();//猫吃鱼... 即调用方法时, 按照从子类(运行类型)开始查找方法
        // ,然后调用, 规则和前面我们讲的方法调用规则一致
        animal.run();//跑
        animal.show();//hello, 你好
        animal.sleep();//睡
        System.out.println("ok~");
    }
}

多态的向下转型

1)语法: 子类类型 引用名 = (子类类型) 父类引用;
2)只能强转父类的引用, 不能强转父类的对象
3)要求父类的引用必须指向的是当前目标类型的对象
4)当向下转型后, 可以调用子类类型的所有成员

public class PoyDetail {
    public static void main(String[] args) {
        //向上转型: 父类的引用指向了之类的对象
        //语法: 父类类型 引用名 = new 子类类型();
        Animal animal = new Cat();

        //我们希望可以调用Cat的 catchMouse方法
        //多态的向下转型
        //(1)语法: 子类类型 引用名 = (子类类型) 父类引用;
        //cat 编译类型 Cat, 运行类型 Cat
        Cat cat = (Cat) animal;

        System.out.println("animal=" + animal);//com.zzw.poly_.detail_.Cat@5cad8086
        System.out.println("cat=" + cat);//com.zzw.poly_.detail_.Cat@5cad8086

        cat.catchMouse();//猫抓老鼠
        //(2)要求父类的引用必须指向的是当前目标类型的对象
         Dog dog = (Dog) animal;//可以吗?

        System.out.println("ok~");
    }
}

属性没有重写之说

属性的值看编译类型 PolyDetail02.java

public class PolyDetail02 {
    public static void main(String[] args) {
        //属性没有重写之说! 属性的值看编译类型
        Base base = new Sub();//向上转型
        System.out.println(base.count);//? 直接看编译类型 10
        Sub sub = new Sub();
        System.out.println(sub.count);//? 20
    }
}

class Base { //父类
    int count = 10;//属性
}
class Sub extends Base { //子类
    int count = 20;//属性
}

instanceOf比较操作符

用于判断对象的运行类型是否为XX类型(接口/类)或XX类型的子类型 PolyDetail03.java

public class PolyDetail03 {
    public static void main(String[] args) {
        BB bb = new BB();
        //instanceOf,比较操作符
        //用于判断对象的类型是否为XX类型或XX类型的子类型
        System.out.println(bb instanceof BB);// true
        System.out.println(bb instanceof AA);// true

        System.out.println("=======================");
        //aa 编译类型 AA, 运行类型是BB
        AA aa = new BB();
        System.out.println(aa instanceof AA);//true
        System.out.println(aa instanceof BB);//true

        System.out.println("=======================");
        Object obj = new Object();
        System.out.println(obj instanceof AA);//false

        System.out.println("=======================");
        String str = "hello";
        //Inconvertible types; cannot cast 'java.lang.String' to 'com.zzw.poly_.detail_.AA'
        //System.out.println(str instanceof AA);
        System.out.println(str instanceof Object);//true
    }
}
class AA {} //父类
class BB extends AA{} //子类

🐟课堂练习

com.zzw.poly_.exercise_包: PolyExercise01.java

public class PolyExercise01 {
    public static void main(String[] args) {
        double d = 13.4;
        long l = (long) d;//ok
        System.out.println(l);//13

        //Inconvertible types; cannot cast 'int' to 'boolean'
        int i = 5;
        boolean b = (boolean) i;//不对, boolean -> int是不可以的

        Object obj = "Hello";//可以, 向上转型
        String objStr = (String) obj;//可以, 向下转型
        System.out.println(objStr);//hello

        Object objPri = new Integer(5);//可以, 向上转型
        //要求父类的引用必须指向的是当前目标类型的对象
        String str = (String) objPri;//错误, 指向Integer的父类引用, 转成String
        Integer str1 = (Integer) objPri;//可以, 向下转型
    }
}

PolyExercise02.java

public class PolyExercise02 {//主类
    public static void main(String[] args) {
        Sub sub = new Sub();
        System.out.println(sub.count);//20
        sub.display();//20
        Base base = sub;//向上转型
        System.out.println(base == sub);//true
        System.out.println(base.count);//10
        //调用方法时, 从运行类型开始建立查找的关系
        base.display();//20
    }
}

class Base {//父类
    int count = 10;

    public void display() {
        //属性没有重写一说!属性的值看编译类型
        System.out.println(this.count);//10
    }
}

class Sub extends Base {//子类
    int count = 20;

    public void display() {
        System.out.println(this.count);//20
    }
}

🐟动态绑定机制

Java重要特性: 动态绑定机制 DynamicBinding.java com.zzw.poly_.dynamic_

public class DynamicBinding {
    public static void main(String[] args) {
        A a = new B();//向上转型
        //a.sum()实际上调用的是运行类型的sum方法, 从运行类型开始建立查找关系
        // a的 编译类型 A, 运行类型 B
        System.out.println(a.sum());// 取消注销子类的sum方法, 输出40
        System.out.println(a.sum());// 注销子类的sum方法后, 输出30
        System.out.println(a.sum1());//取消注销子类的sum1方法, 输出30
        System.out.println(a.sum1());//注销子类的sum1方法, 输出20
    }
}
class A { //父类
    public int i = 10;

    //动态绑定过机制:
    //1.当调用对象方法的时候, 该方法会和该对象的内存地址/运行类型绑定
    //2.当调用对象属性时, 没有动态绑定机制, 即哪里声明, 哪里使用
    public int sum() {//父类的sum()
        //调用子类的getI()
        return getI() + 10;// 20+10
    }

    public int sum1() {
        //属性没有重写一说! 属性的值看编译类型
        return this.i + 10;// 10+10
    }

    public int getI() {
        return i;//10
    }
}
class B extends A {
    public int i = 20;

    //public int sum() {
    //    return i + 20;// 20+20
    //}

    //public int sum1() {
    //    return i + 10;// 20+10
    //}

    //getI()方法被重写了
    public int getI() {
        return i;//20
    }
}

🐟多态数组

1)多态数组, com.zzw.poly_.polyarr包 PolyArr,java
数组的定义类型为父类类型, 里面保存的实际元素类型为子类类型

应用实例: 现有一个继承结构如下, 要求创建1个Person对象, 2个Student对象和2个Teacher对象, 统一放在数组中, 并调用每个对象的say方法.

应用实例升级: 如果调用子类特有的方法, 比如Teacher有一个teach方法, Student有一个study方法, 怎么调用?

public class Person {
    private String name;
    private int age;

    public String say() {
        return "姓名 " + name + "\t年龄 " + age;
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }
}
public class Student extends Person {
    private double score;

    //重写父类的say方法
    public String say() {
        return super.say() + "\t成绩 " + score;
    }

    //特有方法
    public void study() {
        System.out.println("学生 " + getName() + " 正在学Java课程...");
    }

    public Student(String name, int age, double score) {
        super(name, age);
        this.score = score;
    }

    public double getScore() {
        return score;
    }
}
public class Teacher extends Person {
    private double salary;

    //重写父类的say方法
    public String say() {
        return super.say() + "\t薪水 " + salary;
    }

    //特有方法
    public void teach() {
        System.out.println("老师 " + getName() + " 正在讲Java课程...");
    }

    public Teacher(String name, int age, double salary) {
        super(name, age);
        this.salary = salary;
    }

    public double getSalary() {
        return salary;
    }
}
public class PolyArr {
    public static void main(String[] args) {
        //现有一个继承结构如下, 要求创建1个Person对象,2个Student对象2个Teacher对象,
        //统一放在数组中, 并调用每个对象的say方法.

        Person[] persons = new Person[5];
        persons[0] = new Person("赵志伟", 23);
        persons[1] = new Student("赵培竹", 22, 98);
        persons[2] = new Student("mary", 21, 88);
        persons[3] = new Teacher("jack", 22, 15000);
        persons[4] = new Teacher("scott", 20, 17000);

        //循环遍历多态数组, 调用say方法
        for (int i = 0; i < persons.length; i++) {
            //提示: person[i] 编译类型是 Person, 运行类型是根据实际情况由JVM机来判断
            System.out.println(persons[i].say());//动态绑定机制
            //不能调用子类的特有的成员
            //因为在编译阶段, 能调用哪些成员, 是由编译类型来决定的
            if (persons[i] instanceof Student) {//判断person[i] 的运行类型是不是Student
                Student student = (Student) persons[i];
                student.study();//向下转型
            } else if (persons[i] instanceof Teacher) {
                Teacher teacher = (Teacher) persons[i];
                teacher.teach();
            } else if (persons[i] instanceof Person) {

            } else {
                System.out.println("你的类型有误, 请自己检查...");
            }
        }
    }
}

🐟多态参数

方法定义的形参类型为父类类型, 实参类型允许为子类类型
应用实例1: 前面的主人喂动物
应用实例2: com.zzw.poly_.polyparameter_包 PolyParameter.java
定义员工类Employee, 包含姓名和月工资[private], 以及计算年工资getAnnual的方法. 普通工人和经理继承了员工, 经理类多了奖金bonus属性和管理manage方法, 普通工人类多了work方法, 普通工人和经理类要求分别重写getAnnual方法. 如果没说什么字段,默认private

测试类中添加一个方法showEmpAnnual(Employee e), 实现获取任何员工对象的年工资, 并在main方法中调用该方法 [e.getAnnual()]

测试类中添加一个方法testWork(). 如果是普通员工, 则调用work方法; 如果是经理, 则调用manage方法

public class Employee {
    private String name;//姓名
    private double salary;//月工资

    //计算年工资
    public Double getAnnual() {
        return 12 * salary;
    }

    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }

    public String getName() {
        return name;
    }
}
public class Worker extends Employee {

    public Worker(String name, double salary) {
        super(name, salary);
    }

    public void work() {
        System.out.println("普通员工 " + getName() + " 工作中...");
    }

    public Double getAnnual() {//因为普通员工没有其它的收入, 则直接调用父类的方法即可
        return super.getAnnual();
    }
}
public class Manager extends Employee {
    private double bonus;//奖金

    public Manager(String name, double salary, double bonus) {
        super(name, salary);
        this.bonus = bonus;
    }

    public void manage() {
        System.out.println("经理 " + getName() + " 在管理工作中...");
    }

    //重写获取年薪的方法
    public Double getAnnual() {
        return super.getAnnual() + bonus;
    }
}
public class PolyParameter {
    public static void main(String[] args) {
        Worker tom = new Worker("tom", 3000);
        Manager mary = new Manager("mary", 5000, 200000);

        PolyParameter polyParameter = new PolyParameter();
        polyParameter.showEmpAnnual(tom);
        polyParameter.showEmpAnnual(mary);//动态绑定机制

        polyParameter.testWork(tom);
        polyParameter.testWork(mary);
    }

    public void showEmpAnnual(Employee e) {
        System.out.println(e.getAnnual());
    }

    public void testWork(Employee e) {
        if (e instanceof Worker) {
            Worker worker = (Worker) e;//向下转型
            worker.work();
        } else if (e instanceof Manager) {
            Manager manager = (Manager) e;//向下转型
            manager.manage();
        } else {
            System.out.println("你的类型有误...");
        }
    }
}

🐧Object类详解

🐟"=="运算符

  • 判断引用类型

“==”运算符比较两个引用类型时用来判断它们的地址是否相等,即判断它们是否指向同一个对象。

		String str1 = new String("eee");
        String str2 = new String("eee");
        //同一个对象
        System.out.println(str1 == str2);//false
        A a = new A();
        A b = a;
        A c = b;
        //指向的是同一个对象
        System.out.println(a == c);//true
        B b = a;//class B extends A(){}
        System.out.println(b == a);//true
  • 判断基本数据类型

"=="运算符比较的是两个基本数据类型值是否相等

		int i = 10;
		double d = 10.0;
		System.out.println(i == d);//true

🐟equals方法

==和equals的对比 com.zzw.object_: Equals01.java
== 是一个比较运算符

  1. ==: 既可以判断基本类型, 又可以判断引用类型
  2. ==: 如果判断基本类型, 判断的是值是否相等.
  3. ==: 如果判断引用类型, 判断的是地址是否相等, 即判断是不是同一个对象

equals是Object类中的方法,只能判断引用类型。
默认比较两个对象是否是同一个对象

public boolean equals(Object obj) {
        return (this == obj);
    }
  • String重写equals()

String作为Object的子类,重写了父类的equals方法,用于判断内容是否相等。

public boolean equals(Object anObject) {
		//首先判断是否是同一个对象
        if (this == anObject) {
            return true;
        }
        //如果传进来的参数是字符串,判断内容是否相等
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        //既不是同一个对象,参数又不是字符串
        return false;
    }

运行实例

		String str1 = new String("eee");
        String str2 = new String("eee");
        String str3 = new String("eee333");
        Person person1 = new Person("zzw", 22);
        //Object类中的equals方法只能判断两个对象的地址是否相等(引用类型)
        //String、Integer作为Object的子类,重写了equals方法,用于判断内容是否相等
        System.out.println("如果是同一个对象,返回true");
        System.out.println(str1.equals(str1));
        System.out.println(person1.equals(person1));
        System.out.println("如果传进来的是字符串,值相等,返回true");
        System.out.println(str1.equals(str2));
        System.out.println("如果传进来的是字符串,值不相等,返回false");
        System.out.println(str2.equals(str3));
        System.out.println("如果既不是同一个对象,传进来的又不是一个字符串,返回false");
        System.out.println(str1.equals(person1));
  • Integer重写equals()

Integer作为Object的子类,重写了父类的equals方法,integer.equals()比较的是值是否相等

public boolean equals(Object obj) {
		//如果传进来的参数是Integer类型,则比较值是否相等
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        //如果传进来的参数不是Integer类型,则返回false
        return false;
    }

运行实例

		System.out.println("integer.equals()比较的是值");
        Integer integer1 = new Integer(1000);
        Integer integer2 = new Integer(1000);
        int n1 = 1000;
        System.out.println(integer1.equals(integer2));//true
        System.out.println(integer1.equals(n1));//true
  • 图解
名称概念用于基本数据类型用于引用类型
==比较运算符可以,判断值是否相等可以,判断指向的是否是同一个对象
equalsObject类的方法不可以可以,默认判断两个对象是否是同一个对象。
  • 自己重写equals方法

目标:用于判断两个Person对象的内容是否相等
思路:从Object类中copy一份过来

    public boolean equals(Object obj) {
    	//默认是比较的两个对象的地址
        return (this == obj);
    }

重写后的equals方法

//子类重写了Object的方法
@Override
public boolean equals(Object obj) {
   	//this是调用这个方法的对象
   	if(this == obj) {
   		return true;
   	}
-------------------------------------------------------------------------------------------
   	/*写法一*/
   	//如果obj的运行类型是Person
   	if(obj instanceof Person) {
   		//向下转型
   		Person p = (Person) obj;
   		//两层含义:1.如果内容相等,返回true;2.如果内容不相等,返回false
   		return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
   	}
   	//如果不是Person类型的对象
       return false;
-------------------------------------------------------------------------------------------
    /*写法二:过关斩将法*/
    if(!(obj instanceof Doctor)) {
           return false;
       }
       Doctor doctor = (Doctor)obj;
       return doctor.age == this.age && doctor.gender == this.gender &&
               doctor.job.equals(this.job) && doctor.name.equals(this.name) &&
               doctor.salary == this.salary;
   }

主类:

public class EqualsExercise01 {
	public static void main(String[] args) {
		Person person1 = new Person("zzw", 22, '男');
		Person person2 = new Person("zzw", 22, '男');
		System.out.println(person1.equals(person2));
	}
}

Person类

class Person {
	private String name;
    private int age;
    private char gender;
    
    public Person(String name, int age, char gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    @Override
    public boolean equals(Object obj) {
    	if(this == obj) {
    		return true;
    	}
    	if(obj instanceof Person) {
    		Person p = (Person) obj;
    		return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
    	}
        return false;
    }
}
  • 课堂练习
public class EqualsExercise02 {
    public static void main(String[] args) {
        Person1 person1 = new Person1();
        Person1 person2 = new Person1();
        person1.name = "zzw";
        person2.name = "zzw";
        System.out.println(person1 == person2);//不是同一个对象,返回false
        System.out.println(person1.name.equals(person2.name));//String已经重写了equals方法,返回true
        System.out.println(person1.equals(person2));//Person没有重写equals方法,此时还是比较地址是否相同
    }
}
class Person1 {
    public String name;
}

🐟hashCode()方法

public class HashCode_ {
    public static void main(String[] args) {
        AA aa = new AA();
        AA aa1 = new AA();
        AA aa2 = new AA();
        aa2 = aa;
        System.out.println("aa,aa2指向同一个对象");
        System.out.println("aa.hashCode()=" +aa.hashCode());
        System.out.println("aa2.hashCode()=" + aa2.hashCode());
        System.out.println("aa1指向不同对象");
        System.out.println("aa1.hashCode()=" + aa1.hashCode());
    }
}
class AA { }

运行结果
在这里插入图片描述

🐟toString()方法

源码:

public String toString() {
       return getClass().getName() + "@" + >Integer.toHexString(hashCode());
 }

(1)获取类的全类名(包名+类名)
(2)将对象的hashCode值转为十六进制

  • 重写toString()方法

1.alt + insert -> toString键

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2.调用toString(), 直接输出类名

    public static void main(String[] args) {
        Monster monster = new Monster("小钻风", "巡山的", 20000);
        System.out.println(monster);//默认等于monster.toString();
    }

🐟finalize()方法

Car car = new Car();
car = null;
//垃圾回收机制的调用,由系统决定
System.gc();

1.在销毁对象前,会调用该对象的finalize()方法,可以写一些业务逻辑代码在该方法中,比如释放资源:数据库连接、或者是打开的文件;
2.如果不重写finalize()这个方法,则会默认调用Object的finalize()方法;

class Car {
    private String name;
    @Override
    protected void finalize() throws Throwable {
        System.out.println("我们销毁这个对象:" + name);
        System.out.println("释放了资源………");
    }
}

🐧断点调试-breakpoint

1.F7,alt+shift+F7
跳入-Step Into【默认不允许跳入class中】
强制进入-Force Step Into
2.F8,
跳过-Step Over:[一行语句一行语句的执行]
3.Shift+F8,
跳出-Step Out
4.F9,
Resume,执行到下一个断点
动态下断点,既可以在自己写的代码中设置断点,也可以在源码中设置断点
配置:settings->Build,Execution,Deployment->Debugger->Stepping->取消勾选java., javax.
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~ 小团子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值