面向对象编程(基础)

面向对象与面向过程(理解)

  • 1.面向过程:强调的是功能行为,以函数为最小单位,考虑怎么做。
  • 2.面向对象:强调具备了功能的对象,以类/对象为最小单位,考虑谁来做。

JVM内存结构

  • 编译完源程序以后,生成一个或多个字节码文件。
  • 我们使用JVM中的类的加载器和解释器对生成的字节码文件进行解释运行。意味着,需要将字节码文件对应的类加载到内存中,涉及到内存解析。

  • 虚拟机栈,即为平时提到的栈结构。我们将局部变量存储在栈结构中
  • 堆,我们将new出来的结构(比如:数组、对象)加载在对空间中。补充:对象的属性(非static的)加载在堆空间中。
  • 方法区:类的加载信息、常量池、静态域

1、类与对象

1、类与对象的内存分配机制

  • java内存的结构分析

    • 1、栈:一般存放基本数据类型(局部变量)
    • 2、堆:存放对象(Cat cat,数组等)
    • 3、方法区:常量池(常量,比如字符串),类加载信息

    例如:示意图【Cat(name,age,price)】

  • java创建对象的流程简单分析

    Person p=new Person();
    p.name="jack";
    p.age=10;
    
    • 1、先加载Person类信息(属性和方法信息,只会加载一次)
    • 2、在堆中分配空间,进行默认初始化
    • 3、把地址赋给p,p就指向对象
    • 4、进行指定初始化,比如 p.name=“jack”; p.age=10;

2、方法调用机制分析

  • 当程序执行到方法是,就会开辟一个独立的空间(栈空间)
  • 当方法执行完毕,或者执行到 return 语句时,就会返回
  • 返回到调用方法的地方
  • 返回后,继续执行方法后面的代码
  • 当main方法(栈)执行完毕,整个程序退出

3、递归调用

1、重要规则

  • 1、执行一个方法是,就创建一个新的受保护的独立空间(栈空间)
  • 2、方法的局部变量是独立的,不会相互影响
  • 3、如果方法中使用的是引用类型变量(比如数组),就会共享该引用类型的数据
  • 4、递归必须向退出递归的条件逼近,否则就是无限递归,出现StackOverflowError
  • 5、当一个方法执行完毕,挥着遇到return,就会返回,遵守谁调用,就将结果返回给谁,同时当方法执行完毕或者返回时,该方法也就执行完毕

2、打印问题

public void test(int n){if(n>2){test(n-1);}System.out.println("n="+n);
}

3、阶乘问题

public int factorial(int n){if(n==1){retrun 1;}else{return factorial(n-1) * n;}
}

4、方法重载 Overlord

1、重载的好处

  • 减轻了起名的麻烦
  • 减轻了记名的麻烦

2、注意细节

  • 方法名:必须相同
  • 形参列表:必须不同(形参类型或个数或顺序,至少有一样不同,参数名无要求)
  • 返回类型:无要求

5、可变参数

1、基本语法

访问修饰符 返回类型 方法名(数据类型… 形参名){}

2、注意细节

  • 1、可变参数的实参可以为0个或任意多个
  • 2、可变参数的实参可以为数组
  • 3、可变参数的本质就是数组
  • 4、可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
  • 5、一个形参列表中只能出现一个可变参数

6、作用域

1、注意细节

  • 属性和局部变量可以重名,访问时遵循就近原则
  • 在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名
  • 属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。
  • 作用域范围不同
    • 全局变量 / 属性:可以被本类使用,或其他类使用(通过对象调用)
    • 局部变量:只能在本类中对应的方法中使用
  • 修饰符不同
    • 全局变量 / 属性可以加修饰符
    • 局部变量不可以加修饰符

7、构造方法 / 构造器

1、基本语法

【修饰符】 方法名(形参列表){ 方法体; }

2、解释说明

  • 构造器的修饰符可以默认,也可以是public ,protected,private
  • 构造器没有返回值
  • 方法名和类名必须一样
  • 参数列表和成员方法一样的规则
  • 构造器的调用由系统完成
  • 主要作用:完成对新对象的初始化
  • 在创建对象时,系统会自动的调用该类的构造器完成对对象的初始化

3、对象创建流程分析

  • 1、加载Person类信息(Person.class),只会加载一次
  • 2、在堆中分配空间(地址)
  • 3、完成对象初始化
    • 3.1、默认初始化 age = 0,name=null
    • 3.2、显示初始化 age=90 name=null
    • 3.3、构造器的初始化 age=20,name=小倩
  • 4、对象在堆中的地址返回给 p(p是对象名,也可以理解成对象的引用)

8、this关键字

1、注意事项

  • this关键字可以用来访问本类的属性、方法、构造器
  • this用于区分当前类的属性和局部变量
  • 访问成员方法的语法:this.方法名(参数列表)
  • 访问构造器语法:this(参数列表);注意:只能在构造器中使用
  • this不能在类定义的外部使用,只能在类定义的方法中使用

2、this内存分析

public class This01 { //编写一个main方法public static void main(String[] args) {Dog dog1 = new Dog("大壮", 3);System.out.println("dog1的hashcode=" + dog1.hashCode());dog1.info(); System.out.println("============");Dog dog2 = new Dog("大黄", 2);System.out.println("dog2的hashcode=" + dog2.hashCode());dog2.info();}
}class Dog{ //类String name;int age;// public Dog(String dName, int  dAge){//构造器//   name = dName;//    age = dAge;// }//如果我们构造器的形参,能够直接写成属性名,就更好了//但是出现了一个问题,根据变量的作用域原则//构造器的name 是局部变量,而不是属性//构造器的age  是局部变量,而不是属性//==> 引出this关键字来解决public Dog(String name, int  age){//构造器//this.name 就是当前对象的属性namethis.name = name;//this.age 就是当前对象的属性agethis.age = age;System.out.println("this.hashCode=" + this.hashCode());}public void info(){//成员方法,输出属性x信息System.out.println("this.hashCode=" + this.hashCode());System.out.println(name + "\t" + age + "\t");}
}

面向对象编程(中级)

1、包

命名规范

  • com.公司名.项目名.业务模块名

2、访问修饰符

访问级别 访问控制修饰符 同类 同包 子类 不同包
公开 public
受保护 protected ×
默认 default × ×
私有 private × × ×

3、封装

1、注意细节

  • 1、子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性和方法不能在子类直接访问,要通过公关的方法去访问
  • 2、子类必须调用父类的构造器,完成父类的初始化
  • 3、当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过
  • 4、如果希望指定去调用父类的某个构造器,则显示的调用一下:super(参数列表);
  • 5、super在使用时,必须放在构造器第一行(super只能在构造器中使用)
  • 6、super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
  • 7、java所有类都是Object类的子类,Object是所有类的基类
  • 8、父类构造器的调用不限于直接父类;一直往上追溯直到Object类(顶级父类)
  • 9、子类最多只能继承一个父类(指直接继承),即java中是单继承机制
  • 10、不能滥用继承,子类和父类之间必须满足 is-a 的逻辑关系
public class TopBase { //父类是Objectpublic TopBase() {//super(); Object的无参构造器System.out.println("构造器TopBase() 被调用...");//1}
}
public class Base extends TopBase { //父类//4个属性public int n1 = 100;protected int n2 = 200;int n3 = 300;private int n4 = 400;public Base() { //无参构造器System.out.println("父类Base()构造器被调用....");}public Base(String name, int age) {//有参构造器//默认super()System.out.println("父类Base(String name, int age)构造器被调用....");}public Base(String name) {//有参构造器System.out.println("父类Base(String name)构造器被调用....");}//父类提供一个public的方法,返回了n4public int getN4() {return n4;}public void test100() {System.out.println("test100");}protected void test200() {System.out.println("test200");}void test300() {System.out.println("test300");}private void test400() {System.out.println("test400");}//callpublic void callTest400() {test400();}
}
//输入ctrl + H 可以看到类的继承关系
public class Sub extends Base { //子类public Sub(String name, int age) {//1. 老师要调用父类的无参构造器, 如下或者 什么都不写,默认就是调用super()//super();//父类的无参构造器//2. 老师要调用父类的 Base(String name) 构造器//super("hsp");//3. 老师要调用父类的 Base(String name, int age) 构造器super("king", 20);//细节: super在使用时,必须放在构造器第一行//细节: super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器//this() 不能再使用了System.out.println("子类Sub(String name, int age)构造器被调用....");}public Sub() {//无参构造器//super(); //默认调用父类的无参构造器super("smith", 10);System.out.println("子类Sub()构造器被调用....");}//当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器public Sub(String name) {super("tom", 30);//do nothing...System.out.println("子类Sub(String name)构造器被调用....");}public void sayOk() {//子类方法//非私有的属性和方法可以在子类直接访问//但是私有属性和方法不能在子类直接访问System.out.println(n1 + " " + n2 + " " + n3);test100();test200();test300();//test400();错误//要通过父类提供公共的方法去访问System.out.println("n4=" + getN4());callTest400();//}}

2、继承的内存布局

3、继承的本质

/*** 讲解继承的本质*/
public class ExtendsTheory {public static void main(String[] args) {Son son = new Son();//内存的布局//?-> 这时请大家注意,要按照查找关系来返回信息//(1) 首先看子类是否有该属性//(2) 如果子类有这个属性,并且可以访问,则返回信息//(3) 如果子类没有这个属性,就看父类有没有这个属性(如果父类有该属性,并且可以访问,就返回信息..)//(4) 如果父类没有就按照(3)的规则,继续找上级父类,直到Object...System.out.println(son.name);//返回就是大头儿子//System.out.println(son.age);//返回的就是39//System.out.println(son.getAge());//返回的就是39System.out.println(son.hobby);//返回的就是旅游}
}class GrandPa { //爷类String name = "大头爷爷";String hobby = "旅游";
}class Father extends GrandPa {//父类String name = "大头爸爸";private int age = 39;public int getAge() {return age;}
}class Son extends Father { //子类String name = "大头儿子";
}

4、super关键字

1、注意细节

  • super的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用super去访问爷爷类的成员,如果多个基类(上级类)中都有同名的成员,使用super访问就遵循就近原则

2、super和this的比较

No. 区别点 this super
1 访问属性 访问本类中的属性,如果本类没有此属性则从父类中继续查找 从父类开始查找属性
2 调用方法 访问本类中的方法,如果本类中没有此方法从父类继续查找 从父类开始查找方法
3 调用构造器 调用本类构造器,必须放在第一行 调用父类构造器,必须放在第一行
4 特殊 表示当前对象 子类中访问父类对象

5、方法重新 Override

1、注意细节

  • 子类的方法的参数,方法名称要和父类方法的参数,方法名称完全一样

  • 子类方法的返回类型和父类方法返回类型一样,或者是父类返回类型的子类 如:父类返回类型为Object 子类为String

  • 子类方法不能缩小父类方法的访问权限

2、重写和重载的比较

名称 发生范围 方法名 形参列表 返回类型 修饰符
重载(Overload) 本类 必须一样 类型,个数或者顺序至少有一个不同 无要求 无要求
重写(Override) 父子类 必须一样 相同 子类重写的方法,返回的类型和父类返回的类型一致,或者是其子类 子类方法不能缩小父类方法的访问范围

6、多态

1、基本介绍

  • 方法或对象具有多种形态

  • 多态是建立在封装和继承基础之上的

  • 重写,重载就体现了多态

2、注意细节

  • 对象的编译类型和运行类型可以不一致,编译类型在定义时,就确定,不能变化

  • 对象的运行类型是可以变化的,可以通过getClass() 来查看运行类型

  • 多态的前提是:两个对象(类)存在继承关系

  • 属性没有重写之说!属性的值看编译类型

  • instanceof 比较运算符,判断对象的运行类型是什么

    public class PolyDetail03 {public static void main(String[] args) {BB bb = new BB();System.out.println(bb instanceof  BB);// trueSystem.out.println(bb instanceof  AA);// true//aa 编译类型 AA, 运行类型是BB//BB是AA子类AA aa = new BB();System.out.println(aa instanceof AA);System.out.println(aa instanceof BB);Object obj = new Object();System.out.println(obj instanceof AA);//falseString str = "hello";//System.out.println(str instanceof AA);System.out.println(str instanceof Object);//true}
    }
    class AA {} //父类
    class BB extends AA {}//子类//-----------------------------------------------------------------------------public class Homework15 {public static void main(String[] args) {AAA obj = new BBB();//向上转型AAA b1 = obj;System.out.println("obj的运行类型=" + obj.getClass());//BBBobj = new CCC();//向上转型System.out.println("obj的运行类型=" + obj.getClass());//CCCobj = b1;System.out.println("obj的运行类型=" + obj.getClass());//BBB}
    }
    class AAA {}//超类
    class BBB extends AAA {}//父类
    class CCC extends BBB {}//子类
    

3、向上转型

  • 多态是向上转型
  • 本质:父类的引用指向了子类的对象
  • 语法:父类类型 引用名 = new 子类类型();
  • 特点
    • 编译类型看左边,运行类型看右边
    • 可以调用父类中的所有成员(序遵守访问权限)
    • 不能调用子类中的特有成员
    • 最终运行效果看子类的具体实现
public class PolyDetail {public static void main(String[] args) {//向上转型: 父类的引用指向了子类的对象//语法:父类类型引用名 = new 子类类型();Animal animal = new Cat();Object obj = new Cat();//可以吗? 可以 Object 也是 Cat的父类//向上转型调用方法的规则如下://(1)可以调用父类中的所有成员(需遵守访问权限)//(2)但是不能调用子类的特有的成员//(#)因为在编译阶段,能调用哪些成员,是由编译类型来决定的//animal.catchMouse();错误//(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法//,然后调用,规则我前面我们讲的方法调用规则一致。animal.eat();//猫吃鱼..animal.run();//跑animal.show();//hello,你好animal.sleep();//睡//老师希望,可以调用Cat的 catchMouse方法//多态的向下转型//(1)语法:子类类型 引用名 =(子类类型)父类引用;//问一个问题? cat 的编译类型 Cat,运行类型是 CatCat cat = (Cat) animal;cat.catchMouse();//猫抓老鼠//(2)要求父类的引用必须指向的是当前目标类型的对象Dog dog = (Dog) animal; //可以吗?System.out.println("ok~~");}
}//Animal类
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,你好");}}//Cat类
public class Cat extends Animal {public void eat(){//方法重写System.out.println("猫吃鱼");}public void catchMouse(){//Cat特有方法System.out.println("猫抓老鼠");}
}//Dog类
public class Dog extends Animal {//Dog是Animal的子类
}

4、向下转型

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

5、☆java动态绑定机制

  • 当调用对象方法的时候,该方法会和该对象的内存地址 / 运行类型绑定
  • 当调用对象属性时,没有动态绑定机制,哪里声明哪里使用

public class DynamicBinding {public static void main(String[] args) {//a 的编译类型 A, 运行类型 BA a = new B();//向上转型System.out.println(a.sum());//?40 -> 30System.out.println(a.sum1());//?30-> 20}
}class A {//父类public int i = 10;//动态绑定机制:public int sum() {//父类sum()return getI() + 10;//20 + 10}public int sum1() {//父类sum1()return i + 10;//10 + 10}public int getI() {//父类getIreturn i;}
}class B extends A {//子类public int i = 20;//    public int sum() {//        return i + 20;
//    }public int getI() {//子类getI()return i;}//    public int sum1() {//        return i + 10;
//    }
}

6、多态的应用

1、多态数组

  • 数组的定义类型为父类类型,里面保存的实际元素类型为子类类型
public class PloyArray {public static void main(String[] args) {//应用实例:现有一个继承结构如下:要求创建1个Person对象、// 2个Student 对象和2个Teacher对象, 统一放在数组中,并调用每个对象say方法Person[] persons = new Person[5];persons[0] = new Person("jack", 20);persons[1] = new Student("mary", 18, 100);persons[2] = new Student("smith", 19, 30.1);persons[3] = new Teacher("scott", 30, 20000);persons[4] = new Teacher("king", 50, 25000);//循环遍历多态数组,调用sayfor (int i = 0; i < persons.length; i++) {//老师提示: person[i] 编译类型是 Person ,运行类型是是根据实际情况有JVM来判断System.out.println(persons[i].say());//动态绑定机制//这里大家聪明. 使用 类型判断 + 向下转型.if(persons[i]  instanceof  Student) {//判断person[i] 的运行类型是不是StudentStudent student = (Student)persons[i];//向下转型student.study();//小伙伴也可以使用一条语句 ((Student)persons[i]).study();} else if(persons[i] instanceof  Teacher) {Teacher teacher = (Teacher)persons[i];teacher.teach();} else if(persons[i] instanceof  Person){//System.out.println("你的类型有误, 请自己检查...");} else {System.out.println("你的类型有误, 请自己检查...");}}}
}public class Person {//父类private String name;private int 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;}public String say() {//返回名字和年龄return name + "\t" + age;}
}//Student 类
public class Student extends Person {private double score;public Student(String name, int age, double score) {super(name, age);this.score = score;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}//重写父类say@Overridepublic String say() {return "学生 " + super.say() + " score=" + score;}//特有的方法public void study() {System.out.println("学生 " + getName() + " 正在学java...");}
}//Teacher 类
public class Teacher extends Person {private double salary;public Teacher(String name, int age, double salary) {super(name, age);this.salary = salary;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}//写重写父类的say方法@Overridepublic String say() {return "老师 " + super.say() + " salary=" + salary;}//特有方法public void teach() {System.out.println("老师 " + getName() + " 正在讲java课程...");}
}

2、多态参数

  • 方法定义的形参类型为父类类型,实参允许为子类类型
public class PloyParameter {public static void main(String[] args) {Worker tom = new Worker("tom", 2500);Manager milan = new Manager("milan", 5000, 200000);PloyParameter ployParameter = new PloyParameter();ployParameter.showEmpAnnual(tom);ployParameter.showEmpAnnual(milan);ployParameter.testWork(tom);ployParameter.testWork(milan);}//showEmpAnnual(Employee e)//实现获取任何员工对象的年工资,并在main方法中调用该方法 [e.getAnnual()]public void showEmpAnnual(Employee e) {System.out.println(e.getAnnual());//动态绑定机制.}//添加一个方法,testWork,如果是普通员工,则调用work方法,如果是经理,则调用manage方法public void testWork(Employee e) {if(e instanceof  Worker) {((Worker) e).work();//有向下转型操作} else if(e instanceof Manager) {((Manager) e).manage();//有向下转型操作} else {System.out.println("不做处理...");}}
}//父类
public class Employee {private String name;private double salary;public Employee(String name, double salary) {this.name = name;this.salary = salary;}//得到年工资的方法public double getAnnual() {return 12 * salary;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getSalary() {return salary;}public void setSalary(double salary) {this.salary = salary;}
}//子类 Manager
public class Manager extends Employee{private double bonus;public Manager(String name, double salary, double bonus) {super(name, salary);this.bonus = bonus;}public double getBonus() {return bonus;}public void setBonus(double bonus) {this.bonus = bonus;}public void manage() {System.out.println("经理 " + getName() + " is managing");}//重写获取年薪方法@Overridepublic double getAnnual() {return super.getAnnual() + bonus;}
}//子类 Worker
public class Worker extends Employee {public Worker(String name, double salary) {super(name, salary);}public void work() {System.out.println("普通员工 " + getName() + " is working");}@Overridepublic double getAnnual() { //因为普通员工没有其它收入,则直接调用父类方法return super.getAnnual();}
}

7、Object

1、== 和 equals 的比较

  • == 是一个比较运算符

    • == :既可以判断基本类型,又可以判断引用类型
    • ==:如果判断基本类型:判断的是值是否相等
    • ==:如果判断引用类型:判断的是地址是否相等,即帕努单是不是同一个对象
  • equals 方法
    • equals:是Object类中的方法,只能判断引用类型
    • 默认判断的是地址是否相等,子类往往重写该方法,用于判断内容是否相等
//Object 中equals源码
public boolean equals(Object obj) {return (this == obj);
}//Integer 中equals源码
public boolean equals(Object obj) {if (obj instanceof Integer) {return value == ((Integer)obj).intValue();}return false;
}//String 中equals源码
public boolean equals(Object anObject) {if (this == anObject) {//如果是同一个对象return true;//返回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;//如果两个字符串的所有字符都相等,则返回true}}return false;//如果比较的不是字符串,则直接返回false
}

2、hashCode方法

  • 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的
  • 两个引用,如果指向的是不同对象,则哈希值是不一样的
  • 哈希值主要根据地址号来的,不能完全将哈希值等价于地址

3、toString方法

默认返回:全类名+@+哈希值的十六进制

子类往往重写toString方法用于返回对象的属性信息

public class ToString_ {public static void main(String[] args) {/*Object的toString() 源码(1)getClass().getName() 类的全类名(包名+类名 )(2)Integer.toHexString(hashCode()) 将对象的hashCode值转成16进制字符串public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());}*/Monster monster = new Monster("小妖怪", "巡山的", 1000);System.out.println(monster.toString() + " hashcode=" + monster.hashCode());System.out.println("==当直接输出一个对象时,toString 方法会被默认的调用==");System.out.println(monster); //等价 monster.toString()}
}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;}//重写toString方法, 输出对象的属性//使用快捷键即可 alt+insert -> toString@Overridepublic String toString() { //重写后,一般是把对象的属性值输出,当然程序员也可以自己定制return "Monster{" +"name='" + name + '\'' +", job='" + job + '\'' +", sal=" + sal +'}';}@Overrideprotected void finalize() throws Throwable {System.out.println("fin..");}
}

4、finalize方法

  • 当对象被回收时,系统自动调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作
  • 什么时候回收:当某个对象没有任何引用时,jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁对象,在销毁对象前,会先调用finalize方法
  • 垃圾回收机制的调用,是由系统来决定(即有自己的GC算法),也可以通过System.gc();主动触发垃圾回收机制
//演示 Finalize的用法
public class Finalize_ {public static void main(String[] args) {Car bmw = new Car("宝马");//这时 car对象就是一个垃圾,垃圾回收器就会回收(销毁)对象, 在销毁对象前,会调用该对象的finalize方法//,程序员就可以在 finalize中,写自己的业务逻辑代码(比如释放资源:数据库连接,或者打开文件..)//,如果程序员不重写 finalize,那么就会调用 Object类的 finalize, 即默认处理//,如果程序员重写了finalize, 就可以实现自己的逻辑bmw = null;System.gc();//主动调用垃圾回收器System.out.println("程序退出了....");}
}
class Car {private String name;//属性, 资源。。public Car(String name) {this.name = name;}//重写finalize@Overrideprotected void finalize() throws Throwable {System.out.println("我们销毁 汽车" + name );System.out.println("释放了某些资源...");}
}

JavaSE--第一阶段2相关推荐

  1. JavaSE第一阶段模块四

    第一阶段模块四 异常机制和File类 异常机制(重点) 概念 1.异常在Java语言中主要指程序执行中发生的不正常情况 2.java.lang.Throwable类是Java语言中错误(Error)和 ...

  2. JAVASE第一阶段基础

    JavaSE基础知识 文章目录 JavaSE基础知识 一.Java的语法基础 1.标识符 2.关键字 3.数据类型 (1)整型 (2)浮点型 (3)字符型 (4)布尔型 4.变量 5.常量 6.运算符 ...

  3. JavaSE第一阶段知识概括

    JavaSE基础知识 文章目录 JavaSE基础知识 一.Java的语法基础 1.标识符 2.关键字 3.数据类型 (1)整型 (2)浮点型 (3)字符型 (4)布尔型 4.变量 5.常量 6.运算符 ...

  4. Java学习总结第一阶段

    day1(甘特图)预科阶段 甘特图:让工程项目变成可视化图表,也叫项目进度规划表. 一般由:任务名称.工期.开始时间.完成时间.前置任务.资源名称.日期组成 如下所示,资源名称那就是人的名字,前置任务 ...

  5. 深圳Java培训:Java全链路面试题-第一阶段

    深圳Java培训:Java全链路面试题-第一阶段 1,谈谈对面向对象思想的理解 2,JDK,JRE,JVM有什么区别?Java如 何实现跨平台? 3, ==和equals的区别 4,以下代码的执行结果 ...

  6. javaEE第一阶段知识点

    day01 一 : 第一阶段基础语法 1. 基础语法(Java基本概述.注释.关键字.标识符.注释.变量.常量.数据类型.数据类型转换.流程控制.方法.数组)(周考) 2. 核心部分:面向对象(周考) ...

  7. 计算机ui答辩,KGUT1027 班级UI设计第一阶段成长答辩开始啦

    原标题:KGUT1027 班级UI设计第一阶段成长答辩开始啦 2018年6月13日,KGUT1027 班级( UI 设计专业)第一阶段VI作品评审开始啦. 说实话,KGUT1027 班级的同学学习 U ...

  8. java - 第一阶段总结

    java - 第一阶段总结 递归 递归:能不用就不用,因为效率极低 package over; //递归 public class Fi {public static void main(String ...

  9. 团队项目第一阶段冲刺站立会议08

    一.站立会议信息 这几天很紧张,感觉不能按时完工了,但是,还是要一步一步往前走.站立会议照常进行,今天的会议内容依旧是最近最头疼的那块,貌似在前进的路上遇到了瓶颈,慢慢来吧.周四上课前争取完成第一阶段 ...

  10. 第一阶段团队成员贡献打分

    打分情况: 王栋      10 陈浩东   8 杨洋      6 打分依据: a.通过每天的站立会议发言内容,活跃度,以及提出的建议对于软件的实用度 b.通过在第一阶段的冲刺周期中工作量的大小 c ...

最新文章

  1. 【mysql】成绩单表,找到所有成绩都不及格的所有人
  2. 直播 | ICML 2021论文解读:具有局部和全局结构的自监督图表征学习
  3. oracle最新版本是多少_运维日记|关于Oracle的补丁你需要知道的事
  4. 如何在Chrome中保存您当前的所有标签,以便以后阅读
  5. 概率中比较重要的知识
  6. Raspbian 中国软件源
  7. 作者:杨丽彬,华侨大学信息管理系讲师。
  8. Python导函数的一些相关
  9. cisco 2610 2950 单臂路由得一些心得
  10. smarty 模板php,PHP 模板之Smarty 模板介绍
  11. 什么是CentOS系统?
  12. 「斑愿称为最肝」小狮子前端知识食谱 / 生日之际,好运分享 / 秋招和你手摸手入大厂【史上最全指北】 | CSDN技术征文
  13. 卸载WPS后office图标异常解决办法
  14. LightOJ 1071 Baker Vai(记忆化搜索)
  15. php工作心得简50字,50字简短个人工作总结
  16. 书论94 梁同书《频罗庵论书》
  17. 满足石油管道的测量设备
  18. ARM如何判断合法的立即数
  19. matlab tolfun,非线性方程组求解问题(关于TolFun设置问题)
  20. 计算机辅助设计的教学大纲,天正《计算机辅助设计》课程教学大纲

热门文章

  1. 爬虫【爬取汽车之家新闻】
  2. Blender图解教程:洋葱皮插件Ghostool
  3. 常用系统dll及下载网站
  4. SAP PA PP后台配置
  5. 【论文阅读】22-GMS: Grid-based Motion Statistics for Fast, Ultra-robust Feature Correspondence
  6. Rumor谣传路由协议
  7. 论文阅读【Multi-modal Knowledge-aware Event Memory Network for Social Media Rumor Detection】
  8. 关于unity游戏进程的问题:退出,锁屏,被杀掉等事件
  9. Cocos Store 五一大促来袭!首发新品大放价,还有超多好礼免费拿
  10. php中volist怎么循环,Thinkphp的volist标签嵌套循环使用教程_PHP