🔥博客主页: A_SHOWY
🎥系列专栏:力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_
1.关于IDEA
1.1 IDEA目录
Idea的项目编译后,其class文件会存在out文件重,src存放源文件。
1.2 快捷键
- 删除当前行:CTRL + Y
- 复制当前行: CTRL + D
- 添加注释:CTRL + /
- 自动导入需要的类:ALT + ENTER
- 快速格式化:CRTL + Alt + L(可能会锁住QQ)
- 快速运行: Alt + Shift + F10
- 创建构造器:Alt + insert
- 查看一个类的层级关系:CTRL + H
- 光标放在方法上,CTRL + B,可以定位到哪个类的方法
- 自动分配变量名,在后边加.var
1.3 模板/自定义模板
- main:直接输出 public static void main(String[] args)
- sout:输出模板
- fori:循环模板
2.包
2.1 作用
- 区分相同名字的类
- 类很多的时候,可以很好的管理类
- 控制访问范围
2.2 基本语法
package(关键字,表示打包) com.hspedu(表示包名)
2.3 包的本质分析
包的本质是创建不同文件夹保存类文件
2.4 例子:
java">package com.test;import com.xiaoming.Dog;//默认是小明public class reDog {public static void main(String[] args) {Dog dog = new Dog();System.out.println(dog);com.xiaoqiang.Dog dog1 = new com.xiaoqiang.Dog();System.out.println(dog1);}
}
2.5 包的命名
规则:只能包含数字字母下划线小圆点,但是不能数字开头,不能关键字保留字
规范:com.公司名.项目名.模块名
2.6常用的包
2.7 如何导入包
建议需要使用到哪个就导入哪个
java">import java.util.Scanner;//导入一个类
import java.util.*;//表示将util包下的所有类都导入
用一下utils里面的array(排序)
java">package com.test;
import java.util.Arrays;public class reDog {public static void main(String[] args) {int[] arr = {1,5,3,2,84,35};Arrays.sort(arr);for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}
}
细节
package的作用是声明当前类所在的包,需要放在类的最上面,一个类中只能有一个package,那些import导入放到package的下面
3.访问修饰符
四种访问控制修饰符,用来控制方法和属性的访问权限(范围)
- 公开级别:public修饰,对外公开
- 受保护基本:protected,对子类和同一个包中的类公开
- 默认级别:没有修饰符号,向同一个包的类公开
- 私有级别:private,只有类本身可以访问
3.1 注意事项
- 修饰符可以修饰类中的属性、成员方法和类
- 只有默认和public才能修饰类,遵循上述表
4.面向对象编程的三大特征
封装继承和多态(重点 + 难度)
4.1 封装(encapsulation)
把抽象出的数据(属性)和对数据的操作(方法)封装在一起,数据被保护在内部,程序其他部分只有通过被授权的操作【方法】才能对数据进行操作。
好处
-
隐藏实现的细节 方法<--调用
-
可以对数据进行验证,保证安全和合理性
步骤
- 对属性进行私有化
- 提供一个公共的方法(public)set方法,用于对属性的判断并且赋值,public void setXXX(类型参数名),可以加入数据验证的业务逻辑
- 提供一个公共的get方法,用于获取属性的值public XX getXXX(){//权限判断 return XX;}
案例
快速getset方法:alt + insert
java">package encape;import java.sql.SQLOutput;
import java.util.Scanner;public class encapsolution1 {public static void main(String[] args) {Person person = new Person();
// person.name = "jack";
// person.age = 3000;错误person.setName("jackeda");person.setAge(300);person.setSalary(8000.0);System.out.println(person.info());System.out.println(person.getSalary());}
}class Person{public String name;//名字公开private int age;//年龄私有化private double salary;//工资私有化
// public void setName(){
// this.name = name;
// }
// public String getName(){
// return name;
// 自己写setget方法太慢,快捷键,然后根据要求完善代码public String getName() {return name;}public void setName(String name) {if(name.length() >= 2 && name.length() <= 6){this.name = name;}else{System.out.println("名字长度不对,2-6长度");}}public int getAge() {return age;}public void setAge(int age) {if(age >= 1 && age <= 120){this.age = age;}else {System.out.println("年龄需要在1-120之间,给默认年龄18");this.age = 18;//给一个默认年龄}}public double getSalary() {
// 设置一个密码System.out.println("请输入密码");Scanner scanner = new Scanner(System.in);if(scanner.next().equals("88918876")){return salary;}else {System.out.println("密码错误");return 0; }}public void setSalary(double salary) {this.salary = salary;}
// 写一个方法返回属性信息public String info(){return "信息为 name = " + name + " age = " + age + " salary = " + salary;
}
}
构造器和封装
如果设置构造器的话,是不是就相当于破解了我们的加密机制,所以在构造器中设置set方法进行判断。可以有效的限制数据。
java">
public class encapsolution1 {public static void main(String[] args) {Person person1 = new Person("smith",2000,8600);System.out.println(person1.info());}
}class Person{public Person() {}
//在构造器里面搞一个set方法判断public Person(String name, int age, double salary) {
// this.name = name;
// this.age = age;
// this.salary = salary;setSalary(salary);setAge(age);setName(name);}
}
4.2 继承(extends)
问题
两个类的属性和方法有很多是相同的,代码复用较多,较为冗余 =》继承,当多个类 存在相同的属性和方法的时候,可以从这些类中抽象出父类,在父类中定义相同的属性和方法,只需要通过extends声明继承父类即可。 A类就叫父类(基类),B类、C类为子类(派生类)
语法
class 子类 extends 父类{},子类会自动拥有父类定义的属性和方法
实例 :继承机制解决代码冗余
java">//extends01
package com.jicheng;public class extends01 {public static void main(String[] args) {Pupil pupil = new Pupil();pupil.name = "银角大王";pupil.age = 15;pupil.testing();pupil.setScore(60);pupil.showInfo();System.out.println("===============");Graduate graduate = new Graduate();graduate.name = "金角大王";graduate.age = 22;graduate.setScore(59);graduate.showInfo();}
}//Graduate
package com.jicheng;public class Graduate extends Student {public void testing(){System.out.println("大学生" + name + "正在考小写数学");}
}//Pupil
package com.jicheng;public class Pupil extends Student {public void testing(){System.out.println("小学生" + name + "正在考小写数学");}
}//Student
package com.jicheng;public class Student {
//共有属性public String name;public int age;public double score;
//共有方法public void setScore(double score){this.score = score;}public void showInfo(){System.out.println("学生名" + name + "年龄" + age + "成绩" + score);}
}
细节
- 子类继承了父类的所有方法和属性,但是私有属性不能在子类中直接访问,要通过父类提供的公共的方法去访问 例如
java">//对于私有属性和私有方法 //在父类中 class Fulei{ private n4; public getn4(){ return n4; }private test400(){ System.out.println("test400"); } public void callTest400(){test400(); } }//子类中 class Zilei extends Fulei{ System.out.println(getn4()); callTest400(); }
-
子类必须调用父类的构造器,完成父类的初始化,他其实有个super 的一个动作super();默认调用父类的无参构造器。
java"> //子类 public class Graduate extends Student {public Graduate() {//super();默认调用父类的无参构造器System.out.println("子类构造器被调用");} }//父类 public class Student { //共有属性public Student() {System.out.println("父类构造器被调用");} } public class extends01 {public static void main(String[] args) {} }
-
当创建子类对象的时候,不管使用子类的哪个构造器,默认情况下总会调用父类的无参构造器,如果父类没有提供,则必须在子类中用super去指定使用哪个父类的构造器完成初始化否则不通过。
java">//父类 // public Student() { // System.out.println("父类构造器被调用"); // }public Student(String name) {System.out.println("public Student(String name)构造器被调用");} //默认构造器没了。做一个有参的,默认的被覆盖了//就要用super //子类 package com.jicheng;public class Graduate extends Student {public Graduate() {super("jack");System.out.println("子类构造器被调用");}public void testing(){System.out.println("大学生" + name + "正在考小写数学");} }
-
如果希望调用某个父类构造器,则显示的调用以下super(参数列表)。
-
super使用时,需要放在构造器第一行
-
super和this都只能在构造器第一行使用,因此两个方法不能在同一个构造器
-
Object是所有类的基类(ctrl + H可以看类的继承关系)
-
父类构造器的调用不限于直接父类,将会一直追溯到Object类(顶级父类)
-
子类最多继承一个父类,java 是单继承机制
-
如何让A类继承B类和C类呢,通俗来说就是你不可以当我爸爸,但是你能当我爷爷。A继承B,B继承C。也就相当高于A继承了C
本质分析(重要)
加载类信息,从最父类开始加载,在堆中先给爷爷分配空间,再给爸爸开空间最后给儿子。
找属性的话,从底部(最子类)向上找(近的),如果允许访问,直接输出,如果private就不能访问。就报错 。如果比如说爸爸类有age但是私有,爷爷也有,还是找不到,因为在爸爸这里已经找到了但是没权限报错。
练习1
this指的是调用本类的构造器带有abc这个参数的构造器也就是下边那个
有个默认super 所以答案为a,b_name,b
我是A类,B类 有参,C类有参,C类无参
练习2
java">//Computer父类
package test3;public class Test3 {public static void main(String[] args) {PC pc = new PC("intex",16,500,"IBM");pc.printInfo();}}
class Computer {private String cpu;private int memory;//内存private int disk;//硬盘public Computer(String cpu, int memory, int disk) {this.cpu = cpu;this.memory = memory;this.disk = disk;}
// 返回Computer详细信息public String getDetails(){return "cpu=" + cpu + "memory=" + memory + "disk= " + disk;}
//get set方法public String getCpu() {return cpu;}public void setCpu(String cpu) {this.cpu = cpu;}public int getMemory() {return memory;}public void setMemory(int memory) {this.memory = memory;}public int getDisk() {return disk;}public void setDisk(int disk) {this.disk = disk;}
}
java">//PC子类
package test3;public class PC extends Computer{private String brand;public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}//Idea根据继承规则自动把构造器调用写好,父类的熟属性由父类初始化,子类的属性由子类的构造器初始化(继承的基本思想)public PC(String cpu, int memory, int disk, String brand) {super(cpu, memory, disk);this.brand = brand;}//返回PC信息,调用父类的getdetails方法得到相关属性public void printInfo(){System.out.println("PC信息如下");System.out.println(getDetails() + "brand =" + brand);}}
4.3 super关键字
super:代表父类的引用,用于访问父类的属性方法和构造器
基本语法
- 访问父类的属性,但是不能访问父类private的属性。如下只能访问n1,n2,n3,语法是super.属性
java">//父类 package super1;public class A {public int n1 = 100;protected int n2 = 200;int n3 = 300;private int n4 = 400; } //子类 package super1;public class B extends A{public void hi(){System.out.println(super.n1 +super.n2 + super.n3);} }
- 可以访问父类的方法,但是不能访问父类的私有方法,语法是super.方法(参数列表),例子和上面属性一样
- 访问父类的构造器,super只能放在构造器的第一句,且只能一句super,默认是调无参的,想调哪个就写参数。
细节
- 调用父类构造器的好处(分工明确,父类属性由父类初始化,子类属性由子类初始化)上述例子有说过,子类用的时候只不过调用一下
- 当子类中有父类中的成员(属性和方法)重名的时候,为了访问父类成员,必须用super区分。如果没有重名,super,this,直接访问的效果一样的(重要)找方法时候,先找本类如果有可以调用直接调用,如果没有再找父类。父类没有就继续找父类的父类,知道Object类。如果找到了但是不能访问(私有),报错cannot access。如果没有找到,会报错不存在。this.cal和cal寻找的逻辑一样,super.cal逻辑是直接找父类。属性和方法寻找顺序和方法一样,具体看示例图。
- super的访问不限于父类,如果有爷爷类有同名方法,也可以用super去访问爷爷类成员。如果基类都有同名的成员,使用super访问遵循就近原则A -> B -> C
4.4 方法重写/覆盖(override)
介绍:
方法覆盖:子类有一个方法和父类的某个方法的名称、返回类型和参数完全一样,就是子类的方法覆盖了父类的方法。
细节:
- 子类和父类方法的名称和参数列表相同
- 子类方法的返回类型和父类方法的返回类型要一样,或者是父类的返回类型是子类
- 子类方法不能缩小父类方法的访问权限 public > protected > 默认 > private
练习一: 方法重载和重写的区别
练习二
javascript">//主类
package override1;public class override_1
{public static void main(String[] args) {Person jack = new Person("jack", 11);System.out.println(jack.say());Student tom = new Student("Tom", 12, 88918876, 87.5);System.out.println(tom.say());}
}
java">//Person类
package override1;public class Person {private String name;private int age;public String say(){return "name = " + name + "age = " + age;}public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}
java">//Student类
package override1;public class Student extends Person{private int id;private double score;public String say(){return super.say() + "id = " + id + "score = " + score;//用super调用父类的再加上子类的即可}public Student(String name, int age, int id, double score) {super(name, age);this.id = id;this.score = score;}
}
4.5 多态
简单介绍
多态:方法和对象具有多种形态。建立在封装和继承上。
- 方法的多态,重写和重载就体现多态 。
java">package Poly;import static java.lang.Long.sum;public class polyMethod {public static void main(String[] args) {//方法重载体现多态,通过不同的参数去调用sum方法,就会调用不同的方法//因此对sum来说,就是多态的体现A a = new A();System.out.println(a.sum(5,10));System.out.println(a.sum(5,10,20));//方法的重写体现多态,根据对象不一样,会调用不同的方法B b = new B();a.say();b.say();} }class B {public void say(){System.out.println("B方法被调用");} } class A extends B{public int sum(int n1 , int n2){return n1 + n2;}public int sum(int n1, int n2, int n3){return n1 + n2 + n3;}public void say(){System.out.println("A方法被调用");} }
- 对象的多态(核心+重点)(1)一个对象的编译类型和运行类型可以不一致,可以父类的引用指向子类的对象,下面编译类型Animal,运行类型是Dog(2) 编译类型在定义对象时候就确定了不能改变(3)运行类型是可以改变的(4)编译类型看定义时等号的左边,运行类型看等号的右边
例子:对象的多态
如果不使用多态,会发现随着食物和动物种类的增多,代码会变得越来越冗余,很难管理维护,Master类中会出现大量的方法重载
java">//Master类package Poly_01;public class Master {private String name;public Master(String name) {this.name = name;}public String getName() {return name;}public void setName(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());}
}
解决:利用对象的多态,比如再加一个对象在food或者animal的子类一样直接这么管理就行
java">//使用多态机制可以统一管理主人喂食的问题//animal的编译类型是Aniamal,可以接收Animal子类的对象//food编译类型是Food,可以指向Food的子类的对象public void feed(Animal animal,Food food){System.out.println("主人" + name + "给" + animal.getName() + "吃" + food.getName());}
}
细节
- 多态的前提是:两个对象的类存在继承关系
- 多态的向上转型本质:是父类的引用指向了子类的对象/语法:父类中所有满足权限的成员,不能调用子类的特有成员(比如猫的卓老鼠方法)(因为在编译阶段,能调用哪些成员,由编译类型决定)。最终的运行效果要看子类的具体实现 !!!即调用方法时,从子类开始查找方法 然后调用,规则和方法调用规则一致。
- 思考:不能调用特有成员,那我要是想调特有的呢?多态的向下转型 语法:子类类型 引用名 = (子类类型)父类引用。只能强转父类的引用不能强转父类的对象。 (2) 如果你要强转要求i你这个父类引用原先就是指向你这个子类类型。以前比如Animal animal= new Cat();你现在就不能 Dog dog = (Dog) animal; (3)当向下转型后,就可以调用子类类型的所有成员了。
java">Cat cat = (Cat) animal;//向下转型
注意事项
- 属性没有重写之说!!!属性的值看编译类型。
- instanceOf,判断对象的运行类型(左边)是否为某某类型或者其子类型。
练习一
属性找编译类型,调用方法找运行类型,运行类型没找到的去父类找。答案:20,20,true,10,20
4.6 java动态绑定机制(重要)(属性看编译类型,方法看运行类型)
介绍
- 当调用对象方法的时候,该方法和该对象的内存地址/运行类型绑定
- 当调用对象属性的时候,没有动态绑定机制,哪里声明哪里使用
4.7 多态的应用
1.多态数组
数组的定义类型为父类类型,里面保存的实际元素类型为子类类型。
可以看到persons【i】编译类型一致是person,运行类型根据实际情况判断,这样的话say方法非常灵活。
java">//POLY主类
package duotaishuzu;public class PolyArray {public static void main(String[] args) {//因为都要放在一个数组里面,所以用父类创建数组Person[] persons = new Person[5];persons[0] = new Person(20,"jack");persons[1] = new Student("Tom",20,85.2);persons[2] = new Student("Jerry",15,87.6);persons[3] = new Teacher("Tonny",28,3000);persons[4] = new Teacher("Pig",60,15000);
//编译类型事Personfor(int i = 0; i < persons.length; i++){System.out.println(persons[i].say());//做一个判断,做向下类型转换。判断persons【i】的运行类型是不是studentif(persons[i] instanceof Student){Student student = (Student) persons [i];student.study();
//(Student) persons [i].study();}if(persons[i] instanceof Teacher){Teacher teacher = (Teacher) persons[i];teacher.teach();}}}
}
从上面的代码可以看出。要调用特有的方法不能用persons【i】.teach和study直接调用。 用instanceof判断运行类型
java">Person父类
package duotaishuzu;public class Person {private int age;private String name;public Person(int age, String name) {this.age = age;this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String say(){return "name " + name +"\t" + "age" + age;}
}
java">//student和teacher子类
package duotaishuzu;public class Student extends Person{private double score;public Student(String name,int age, double score){super(age,name);this.score = score;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}
//重写父类的say方法@Overridepublic String say(){return(super.say() + score);}public void study(){System.out.println("学生" +getName() + "正在授课");}
}package duotaishuzu;public class Teacher extends Person{private double salary;public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}public Teacher(String name, int age, double salary) {super(age, name);this.salary = salary;}@Overridepublic String say(){return super.say() + salary;}public void teach(){System.out.println("老师:" + getName() + "正在授课");}}
2.多态参数
方法定义的形参类型为父类类型,实参类型允许为子类类型
这道题目的两个难点是一个是动态绑定机制,另一个是多态的下转型。
java">package polypara;import sun.plugin2.applet.ManagerCache;public class poplpara {public static void main(String[] args) {Common tom = new Common("tom", 2000);manager lilan = new manager("lilan", 5000,20000);poplpara poplpara = new poplpara();poplpara.showEmpAnnual(tom);poplpara.showEmpAnnual(lilan);poplpara.testwork(tom);poplpara.testwork(lilan);}public void showEmpAnnual(Employee e){System.out.println(e.getAnnual());//动态绑定机制}public void testwork(Employee e){if(e instanceof Common){((Common) e).work();//多态的下转型}else if(e instanceof manager){((manager) e).manage();}}
}class Employee{public String name;private double salary;public Employee(String name, double salary) {this.name = name;this.salary = salary;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}public String getName() {return name;}public void setName(String name) {this.name = name;}//计算年工资的方法public double getAnnual(){System.out.println("年工资是:");return salary * 12;}
}class Common extends Employee{public Common(String name, double salary) {super(name, salary);}//工作方法public void work(){System.out.println("员工" + getName() + "正在工作");}@Overridepublic double getAnnual() {return super.getAnnual();}
}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() + "正在管理");}@Overridepublic double getAnnual() {return super.getAnnual() + this.bonus;}
}
5.Ocject类
object类是类层次结构的根类,所有的类都能用object类的方法
5.1 ==和eqals的区别
(1)==方法
java">package object;import jdk.nashorn.internal.ir.BaseNode;public class demo {public static void main(String[] args) {A a =new A();A b = a;A c = a;System.out.println(a == c);System.out.println(b == c);B obj = a;System.out.println(obj == c);//只要满足两个对象的地址是一样的,那就是true}
}
//这三个都是true
class A extends B {}class B {}
(2)equals 方法(想找源码的话ctrl+b)
是Object类中的方法,只能判断引用类型,默认判断是否地址相等,子类中往往重写(比如String,integer(这个是int的包装类))
java"> Integer integer = new Integer(1000);Integer integer1 = new Integer(1000);System.out.println(integer1 == integer);//false,因为不是同一个对象System.out.println(integer1.equals(integer));//true。因为已经重写了//String也是同理
(3)练习1 重写equals方法
java">package object;public class duotaichongxie {public static void main(String[] args) {Person person1 = new Person("pig",'男',15);Person person2 = new Person("pig",'男',15);System.out.println(person2.equals(person1));}}
class Person{private String name;private int age;private char gender;//重写一下equalspublic boolean equals(Object obj){if(obj instanceof Person){Person p = (Person) obj;//向下转型,因为我要得到obj的各个属性return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;}else{return false;}}public Person(String name, char gender, int age) {this.name = name;this.gender = gender;this.age = age;}}
练习2
答案:FTFTF
练习3
第一个类型自动转换T,T,T,F,T,F(编译报错)
5.2 hashcode方法
- 提高具有哈希结构容器的效率
- 两个引用,如果指向的是同一个对象,则哈希值一定是一样的
- 两个引用,如果指向的是不同对象,则哈希值不一样
- 哈希值主要根据地址来计算但是不能完全等价于地址
- 我感觉可以理解为内部地址转换为整数,也就是地址的映射
java">package object;
public class hashcode {public static void main(String[] args) {AA aa = new AA();AA aa1 = new AA();AA b = aa;System.out.println(aa.hashCode());//460141958System.out.println(aa1.hashCode());//1163157884System.out.println(b.hashCode());//460141958}
}
class AA{}
5.3 toString方法
1.返回该对象的字符串表示,默认返回的是全类名(包名+ 类名)+ @ +哈希值的十六进制,子类往往重写这个方法,用来返回对象的属性信息
java">package object;
public class Tostring {public static void main(String[] args) {Monster monster = new Monster("小妖怪", "巡山", 5000);System.out.println(monster.toString() + "hashcode=" + monster.hashCode());}
}
//Object的Tostring源码
//(1)getClass().getName()类的全类名(类名+包名)
//(2)Integer.toHexString(hashCode()),将对象的哈希值转为16进制
class Monster{private String name;private String job;private double sal;public Monster(String name,String job,double sal){this.name = name;this.job = job;this.sal = sal;}}
2.重写tostring方法,在打印对象和拼接对象时候输出对象的属性
java"> @Overridepublic String toString() {//重写后一般是把对象的属性输出出来return "Monster{" +"name='" + name + '\'' +", job='" + job + '\'' +", sal=" + sal +'}';}
3.当输出一个对象的时候,toString方法会被默认调用,也就是Syste.out.println(monster);就会默认调用monster,toString()
5.4 finalize方法
- 当对象被回收的时候,系统用该对象的finalize 方法,子类可重写该方法,做一些资源的释放。
- 当某个对象没有任何引用的时候,则jvm‘认为这个对象是个垃圾,会销毁,销毁前会调用finalize
- 垃圾回收机制有自己的GC算法,由系统来决定。垃圾回收机制的主动调用可以通过System.gc()主动触发
java">package object;
public class finalize {public static void main(String[] args) {Car ab = new Car("宝马");ab = null;//这时这个对象就是一个垃圾,垃圾回收器就会销毁,也就是把堆内部分配的空间回收在销毁前会调用该对象的finalize方法//程序猿就可以写自己的业务逻辑(比如释放资:比如数据库连接,或者打开的文件)//如果不重写finalize方法,就会调用object类的finalize默认处理System.gc();//主动调用垃圾回收期System.out.println("程序结束了");}
}
//结果程序结束了
//我们销毁 汽车宝马
//我们释放了资源。。。
class Car{String name;public Car(String name) {this.name = name;}@Overrideprotected void finalize() throws Throwable {System.out.println("我们销毁 汽车" + name);System.out.println("我们释放了资源。。。");}
}
6.断点调试(debug)
在断点调试过程中,是处于一个运行状态,是以对象的运行类型来执行的
6.1快捷键
F7(跳入):跳入方法内
F8(跳过):逐行执行代码
SHIFT+F8:跳出方法
F9(resume):执行到下一个断点
6.2 断点demo1(数组越界)
6.3 断点demo2(追踪源代码)
F7一直往里追可以追到头快排,补:可以动态的加断点