Java基础-面向对象&异常(六)

一、初识面向对象

  1. 面向对象:编程使用的一种编程思路,编程思想
  2. 面向对象和面向过程比较:都是编程思想,面向过程是面向对象的基础,面向对象是基于面向过程的。
    面向过程:更强调解决问题的基本步骤,强调问题的解决方式,更强调的是方法。 面向对象:更强调解决问题的主体,更强调谁来解决这个问题,更强调的是数据,更强调的是对象,更强调的是谁拥有数据和操作数据的权力。
    例子:面向过程:拿盆子,盆子水,洗衣粉,放衣服,搓一搓,揉一揉,刷一刷,晾干 面向对象:洗衣机
  3. 面向对象好处
    (1)更符合人类的思想习惯
    (2)复杂的问题简单化
    (3)由执行者变成了指挥者
  4. 面向对象的特征
    封装
    继承
    多态
  5. 面向对象是面向过程更高层次的编程思想、面向过程是面向对象的基础。面向对象基于面向过程。
  6. 面向过程&面向对象

在这里插入图片描述

二、对方法的提高

(不理解,说明对象和内存还不理解,也可以跳过先看内存和对象就理解呢!)

break与return得区别

break:跳出switch,结束循环!
return: 结束方法,返回一个结果(这个结果为空也可以是其它得类型)!

(1)创建Student类

public class Student {

    //静态 static
    public static void say(){
        System.out.println("学生在说话");
    }

    //非静态
    public void hi(){
   		 System.out.println("hihihi");
    }
}

(2)创建类Static_Method来调用Student

public class Static_Method {

    public static void main(String[] args) {
	//static和类一起加载
        //静态
        Student.say();

        //非静态
        Student student = new Student();
        student.hi();
    }
}

在这里插入图片描述

运行结果为:

在这里插入图片描述

(3)值传递

public class Zhi_ChuanDi {
    //值传递
    public static void main(String[] args) {
        int a = 1;
        System.out.println(a);
        Zhi_ChuanDi.change(a);
        System.out.println(a);
    }
    //返回值为空
    public static void change(int a){
         a = 10;
    }
}

运行结果

在这里插入图片描述

(4)引用传递

public class YinYong_ChuanDi {
//引用传递  本质还是值传递
    public static void main(String[] args) {

        Person person = new Person();
        System.out.println(person.name);

        YinYong_ChuanDi.change(person);

        System.out.println(person.name);
    }
    public static void change(Person person){

        person.name = "Daniel";//person是一个对象指向-------------->  Person person = new Person();这是一个具体的人,可以改变属性!
    }
}
class Person{

    String name;

}

运行结果为:

在这里插入图片描述

三、对象的创建分析

  1. 类:类型,对具体事物的一个抽象认识,是抽象出来的结果,其实就是一个概念
    抽象:抽取事物中,像的相同的相似的内容出来,在人脑中形成一个概念
  2. 对象:事物的具体体现。

在这里插入图片描述

(1)先创建学生类

//学生类
public class Student {

    //属性: 字段
    String name;//null
    int age;//0

    //静态方法
    public static void say(){
        System.out.println("学生在说话");
    }

    //非静态
    public void hi(){
        System.out.println("hihihi");
    }
    public void study(){
        System.out.println(this.name+"在学习");
    }
}

(2)创建抽象类

public class Application_Daniel {

    public static void main(String[] args) {
        //类:抽象的,实例化
        //类实例化后返回一个自己的对象
        //student对象就是一个Student类的具体实例

        Student stu = new Student();

        stu.name = "Wendy";
        int age = 18;

        Student st = new Student();

        st.name = "Kendra";
        st.age = 14;

        System.out.println(st.name);
        System.out.println(st.age);

        System.out.println(stu.name);
        System.out.println(stu.age);

        stu.study();
    }
}

运行结果为:
在这里插入图片描述
4.有无参构造

(1)创建Person类

public class Person {
    //一个类即使什么都不写,它也会存在一个方法
    //显示的定义构造器
    String name;

    int age;
    //1.使用new关键字,本质是在调用构造器
    //2.用来初始化值
    public Person(){

        this.name ="Kendra";
    }
    //有参构造:一旦定义了有参构造,无参就必须显示定义
    public Person(String name){
        this.name = name;
    }

    /**
     * 构造器:
     * 1.和类名相同
     * 2.没有返回值
     * 作用:
     * 1.new 本质在调用构造方法
     * 2.初始化对象的值
     * 注意点:
     * 1.定义有参构造之后,如果想使用无参构造,显示的定义一个无参的构造
     * 
     * Alt+Insert
     */
}

(2)创建抽象Application类

//一个项目应该只存在一个main方法
public class Application {

    public static void main(String[] args) {
        //实例化一个对象
        Person person = new Person();

        person.name ="Daniel";

        System.out.println(person.name);
    }
}

运行结果显示:

在这里插入图片描述

5.类对象的内存理解
(1)创建一个Pet类

public class Pet {

    String name;
    int age;

    public void shout(){
        System.out.println("叫了一声");
    }
}

(2)创建抽象类加载

public class PetApplication {

    public static void main(String[] args) {

        Pet dog = new Pet();

        dog.name="旺财";
        dog.age=3;
        dog.shout();
        System.out.println(dog.name);

        Pet cat = new Pet();
        cat.name="猫咪";
        cat.age=2;
        cat.shout();
        System.out.println(cat.name);
    }
}

运行结果为:

在这里插入图片描述
(3)内存分析
在这里插入图片描述

🌻🌻温故而知新🌻🌻

  1. 类与对象
  • 类是一个模板:抽象,对象是一个具体得实例
  1. 方法
  • 定义,调用!
  1. 对象得引用
  • 引用类型: 基本类型(8)
  • 对象是通过引用来操作得: 栈------> 堆
  1. 属性: 字段Field 成员变量
  • 默认初始化
    – 数字: 0 0.0
    – char : u0000
    – boolean:false
    – 引用: null
  • 修饰符 属性类型 属性名 = 属性值!
  1. 对象得创建和使用
  • 必须使用new 关键字创造对象,构造器 Person daniel = new Person();
  • 对象的属性: daniel.name
  • 对象的方法: daniel.sleep()
  1. 类:
  • 静态的属性 属性
  • 动态的行为 方法

封装,继承,多态 👇🏾👇🏾

四、面向对象三大特性

4.1 封装

在这里插入图片描述

(1)创建Student类

//private 私有的
public class Student {

    private String name;

    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if(age >= 120 || age <= 0){
            this.age = 3;
        }else{
            this.age = age;
        }
    }
}

(2)创建抽象类

/**
 * 封装:
 * 1.提高程序的安全性,保护数据
 * 2.隐藏代码的实现细节
 * 3.统一接口
 * 4.系统可维护增加了
 */
 //判断一个方法相同:Daniel给你教两个方法:
 //(1)看方法名是否相同
 //(2)看参数列表是否一致
public class Student_Application {

    public static void main(String[] args) {
        
        Student student = new Student();

        student.setName("Daniel");

        System.out.println(student.getName());

        student.setAge(999);//不符合实际,因此Student做了判断

        System.out.println(student.getAge());

    }
}

运行结果为:

在这里插入图片描述

4.2 继承

在这里插入图片描述

(1)创建父类

public class Person {

    private double money = 1_0000_0000;

    public void like(){

        System.out.println("喜欢养花");
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

(2)创建子类继承父类

public class Student extends Person {

    public static void main(String[] args) {

        Person person = new Person();

        person.like();

        System.out.println(person.getMoney());
    }
}

运行结果为:

在这里插入图片描述

查看上下级继承:ctrl+h----------------------->所有的类都继承Object类

4.1.1 this & super

(1) 创建父类 Person

public class Person {
    protected String name = "Kendra";
    //private int age = 11;
}

(2)创建子类Student并且继承父类

public class Student extends Person{

    private String name = "Daniel";

    public void su(){

        System.out.println(this.name);  //子类
        System.out.println(super.name); //父类
        //System.out.println(this.age);
    }
}

(3)创建应用抽象类Application

public class Application {

    public static void main(String[] args) {

        Student student = new Student();

        student.su();
    }
}

运行结果为:

在这里插入图片描述

super注意点:

  1. super调用父类的构造方法,必须在构造方法的第一个
  2. super必须只能出现在子类的方法或者构造方法中!
  3. super和this不能同时调用构造方法!
    this || super

(1)代表的对象不同:

  • this:本身调用者这个对象
  • super: 代表父类对象的应用

(2)前提

  • this:没有继承也可以使用
  • super:只能在继承条件才可以使用

(3)构造方法

  • this();本类的构造
  • super():父类的构造!

4.1.2 重写

  1. 在子父类中,出现了不同名的方法
  • 子类可以直接调用父类的方法,也可以调用子类的特有方法
  1. 在子父类中,出现了同名的方法
  • 在子父类中,出现了一模一样的方法声明,而两个方法的实现内容却不一样
  • 作用:在子类中,如果你不想修改父类中的方法声明,但是还想修改方法的实现内容,这时候就需要使用重写。
  1. 方法的重写和方法的重载:
  • 重载:在同一个类中,方法名相同,参数列表不同,与返回值类型无关
  • 重写:在子父类中,方法名相同,参数列表相同,与返回值类型有关(相同)
    别名:Override,覆写、覆盖
  1. 方法重写的检查:
  • @Override
  • 让编译器帮助我们检查,当前的这个方法,究竟是否是对父类方法的重写。
  1. 说明:
  • 方法本身还是属于父类,只是在子类中重新实现了这个方法的内容。

(1)子父类的创建

public class Fu {

    public void chong(){

        System.out.println("父类的方法");
    }
}
class Zi extends Fu{
    @Override
    public void chong() {
        System.out.println("子类的方法");
        super.chong();
    }
}

(2)抽象创建类

public class Application {

    public static void main(String[] args) {

        Fu fu = new Fu();

        fu.chong();

        Fu f = new Zi();

        f.chong();
    }
}

运行结果显示为:

在这里插入图片描述

重写:需要有继承关系,子类重写父类的方法!

  1. 方法名必须相同
  2. 参数列表必须相同
  3. 修饰符:范围可以扩大但不能缩小: public>Protected>Default>private
  4. 抛出的异常:范围,可以缩小,但不能扩大;ClassNotFundException–>Exception(大)
  5. 重写,子类的方法的父类的必要一致;方法体不同!
  6. 为什么需要重写:
  • 父类的功能,子类不一定需要,或者不一定满足!

Alt+Insert; Override;

4.3 多态

在这里插入图片描述

4.3.1 多态中成员变量的访问特点

1、编译看左边,运行看左边

2、编译的时候,要看【=】左边的引用的类型中,是否有该变量的定义,如果有,就编译成功,如果没有,就编译失败。
3、运行的时候,要看【=】左边的引用所属类型中,真正如何给变量赋值的。获取到的是引用父类的赋值结果。

public class BianLiangTeDian {
    public static void main(String[] args) {
		/*
			在多态中成员变量的访问特点
		*/
        Animal zoo = new Cat();
        //2、编译的时候,要看【=】左边的引用的类型中,是否有该变量的定义,如果有,就编译成功,如果没有,就编译失败。
        //System.out.println(zoo.color);
        //3、运行的时候,要看【=】左边的引用所属类型中,真正如何给变量赋值的。获取到的是引用父类的赋值结果。
        System.out.println(zoo.age);
    }
}
class Animal {
    int age = 10 ;

}

class Cat extends Animal {
    int age = 20;
    String color;
}

运行结果为:

在这里插入图片描述

public class Daniel_DuoTai {

    public static void main(String[] args) {

        Animals animals = new Cats();

        System.out.println(animals.name);
        //System.out.println(animals.age);//编译看左边,运行看左边
        /*
			在多态中成员变量的访问特点
			 2、编译的时候,要看【=】左边的引用的类型中,是否有该变量的定义,如果有,就编译成功,如果没有,就编译失败。
            3、运行的时候,要看【=】左边的引用所属类型中,真正如何给变量赋值的。获取到的是引用父类的赋值结果。
		*/

    }

}
class Animals{

    String name;
}
class Cats extends Animals{

    String  name = "Daniel";
    int age = 10;
}

运行结果为:

在这里插入图片描述

4.3.2 多态中成员方法的访问特点

1、编译看左边,运行看右边

2、编译的时候,要看【=】左边的引用所属的类型中,是否有该方法的定义,如果有,就编译成功,如果没有,就编译失败。
3、运行的时候,要看【=】右边的对象所属的类型中,是如何实现这个方法的。最终运行的是子类重写过的方法实现。

public class Daniel_DuoTai {

    public static void main(String[] args) {

            Animals an = new Cats();//父类的引用指向子类的对象

            System.out.println(an.name);
            //成员变量访问特点,编译看=左边,运行也看=左边
            System.out.println(an.age);

            an.eat();//成员方法的访问特点,编译看= 左边,运行看=右边
             //an.run();//没有重写,只能强制转换才可访问如下:
            ((Cats) an).run();
    }

}
class Animals{

    String name;
    int age = 99;

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

//
}
class Cats extends Animals{

    String  name = "Daniel";
    int age = 10;

    @Override
    public void eat() {
        System.out.println("吃酒喝水");
    }

    public void run(){
        System.out.println("全民健身");
    }
}

运行结果为:

在这里插入图片描述

4.3.3 多态中静态方法的访问特点

1、编译看左边,运行看左边

2、编译的时候,要看【=】左边的引用所属的类型中,是否有该方法的定义,如果有,就编译成功,如果没有,就编译失败
3、运行的时候,要看【=】左边的引用所属的类型中,如何实现该方法的。最终运行的是引用所属类型中该方法的实现。(方法属于类,和父类的方法不属于重写关系)
4、静态最终解释:
静态变量:存储在类的字节码中的变量,被所有对象所共享,不随着对象的变化而变化,都有相同的值,所以称为静态变量
静态方法:只会根据引用所属的父类,来决定运行的内容,运行内容,不会随着子类的变化而变化,都是引用所属的父类的方法实现,所以称为静态方法。

public class Daniel_DuoTai {

    public static void main(String[] args) {

            Animals an = new Cats();//父类的引用指向子类的对象
            //编译看左边,运行看左边
            an.speak();
    }

}
class Animals{

    public static void speak(){
        System.out.println("懂礼貌,树新风");
    }
}
class Cats extends Animals{

    //@Override   静态方法不能被重写
    public static void speak(){
        System.out.println("人之初,性本善");
    }
}

运行结果为:

在这里插入图片描述
多态的注意事项

  1. 多态是方法的多态,属性没有多态
  2. 父类和子类,有联系,类型转换异常!ClassCastException!
  3. 存在条件:继承关系,方法需要重写,父类引用指向子类对象!Father f1 = new Son();

哪些方法不能重写:

  1. static方法,属于类,它不属于实例
  2. final常量;
  3. private方法;

4.3.4 instanceof(向上向下转型)

(类型转换)引用类型,判断一个对象是什么类型~

  1. 向上转型:
    使用子类的引用指向子类的对象(正常情况)
    多态中,使用父类的引用指向子类的对象(向上转型)
    本质:缩小了对象本身的访问范围,减少了访问的权限(只能访问父类中定义的内容)
  2. 向下转型:
    概念:
    让指向子类对象的父类引用,【恢复】成子类的引用
    格式:
    子类类型 引用名称 = (子类类型)父类类型的引用
    SuperMan sm = (SuperMan)m;
    本质:
    【恢复】子类类型原本就有的访问范围
public class XiangShangXiangXia {
    public static void main(String[] args) {
        //超人案例

        Man m = new SuperMan();//向上转型.自身的访问权限变小了
        System.out.println(m.name);//普通人的名字
        m.business();
        //m.fly();普通人不能飞,不能调用fly()方法
        //向下转型
        SuperMan sm = (SuperMan)m;

        //double b = 20.3333;
        //int a = (int)b;
       // System.out.println(a);

        sm.fly();

    }
}

class Man {
    String name = "KangKang";

    public void business(){
        System.out.println("卖煎饼果子");
    }
}
class SuperMan extends Man{
    String name = "SpiderMan";

    public void business(){
        System.out.println("敲代码");
    }

    public void fly(){
        System.out.println("我要去拯救世界了");
    }
}

运行结果为:

在这里插入图片描述

4.3.5 static

public class Staticc {
    //2.赋初值
    {
        System.out.println("匿名代码块");
    }
    //1 只执行一次
    static {
        System.out.println("静态代码块");
    }
    //3
    public Staticc() {
        System.out.println("构造代码块");
    }

    public static void main(String[] args) {

        Staticc staticc = new Staticc();
        
    }
}

运行结果为:

在这里插入图片描述

package duotai;
import static java.lang.Math.random;//静态导入包
public class Demo_Daniel {

    public static void main(String[] args) {

        System.out.println(random());
        System.out.println(Math.random());//无需静态导入包
    }
}

在这里插入图片描述

五、抽象类和接口

5.1 抽象类

5.1.1 抽象方法

  1. 抽象:抽取像的、相同的、相似的内容出来
  2. 抽象方法:只有方法声明,而没有方法实现的方法,就是抽象方法
    在各个子类中,对于某个方法都有自己不同的实现,所以实现各不相同,无法抽取,只能抽取方法的声明上来,在父类中,方法就只有方法声明没有方法体。就是抽象方法。
  3. 定义格式:
    (1)没有方法实现,连大括号都没有,直接在方法声明后面加上一个分号,表示方法定义结束 public abstract void test();
    (2)为了将方法标记为抽象方法,需要在方法前面加上一个abstract关键字
//abstract  抽象
public  abstract  class Abstract_Daniel {
    /**
     * 约束~有人帮我们实现
     * abstract ,抽象方法,只有方法名字,没有方法的实现
     */
    public abstract  void main();
    /**
     * 1.不能new这个抽象类,只能靠子类去实现它;约束!
     * 2.抽象类中可以写普通的方法
     * 3.抽象方法,必须在抽象类中
     * 抽象的抽象:约束~
     */
}

5.1.2 抽象类的特点

  1. 抽象类和抽象方法都需要使用abstract关键字修饰
  • 抽象类:abstract class {}
  • 抽象方法:public abstract void test();
  • Public private protected这些称之为修饰符
  1. 抽象类和抽象方法的关系:
  • 抽象方法所在的类必须是抽象类
  • 抽象类中未必一定都定义抽象方法,抽象类中未必存在抽象方法
  1. 抽象类的实例化(抽象类如何创建对象)
  • 抽象类不能直接实例化(不能创建对象)
  • 定义抽象类的子类,由子类创建对象,调用方法
  1. 抽象类子类
  • 在子类中,将父类所有的抽象方法全部重写(实现),子类就成了一个普通类,就可以创建对象
  • 在子类中,没有将父类中所有的抽象方法全部实现,子类就还是一个抽象类,还需要使用abstract关键字修饰子类。
class Daniel_AbstractClass {
	public static void main(String[] args) {
		//Animal an = new Animal();//抽象类不能直接实例化
		Cat c = new Cat();

	}
}
abstract class Animal {
	//抽象方法
	public abstract void speak();
	public abstract void eat();
 
/*	public void sleep(){//抽象类中不一定全部是抽象方法
		System.out.println();
	}*/
}

class Cat extends Animal {

	@Override
	public void speak(){
		System.out.println("喵喵喵");
	
	}
	@Override
	public void eat(){
		System.out.println("猫吃鱼");
	}
}
abstract class Pig extends Animal {
	@Override
	public void speak(){
		System.out.println("哼哼哼");
	}
	public abstract void eat();
}

5.1.3 抽象类成员特点

  1. 成员变量:可以定义变量,也可以定义常量,但是不能被抽象
  2. 构造方法:有
  • 虽然本类无法创建对象,但是抽象类一定有子类,子类会访问父类的抽象方法。
  • 是否有构造方法,不取决于是否可以创建对象,而是取决于是否可以定义成员变量。如果可以定义成员变量,那么就需要初始化成员变量,就是构造方法来完成的。
  1. 成员方法:
  • 既可以是抽象方法:强制子类重写
  • 也可以是非抽象方法:用于给子类继承,提高代码的复用性

5.2 接口

5.2.1 接口的概述

  1. 广义:一切定义规则的都是接口
  2. 狭义:java中用于定义方法命名的规则就是接口
  • Java接口中,全都是方法的声明,都是抽象方法
  1. 好处:
  • 一旦将命名规则定义出来,【方法的调用】和【方法的实现】就分离开了,可以提升开发效率,降低代码的耦合性

在这里插入图片描述
(1)创建接口UserService

public interface UserService {

    void add(String name);
    void delete(String name);
    void update(String name);
    void query(String name);
}

(2)创建接口实现类UserServiceImpl

//interface 关键字
//接口可以多继承
//接口一旦定义就要实现接口
public class UserServiceImpl implements UserService,TimeService {

    @Override
    public void add(String name) {

    }

    @Override
    public void delete(String name) {

    }

    @Override
    public void update(String name) {

    }

    @Override
    public void query(String name) {

    }

    @Override
    public void time() {

    }
}

(3)再次创建接口TimeService

public interface TimeService {
    void time();
}

5.2.2 接口的特点

  1. 接口的定义:使用interface关键字,编译也是生成一个【.class】(字节码文件)文件
interface 接口名称 {
	方法声明的定义;
}
  1. 接口中,只可以声明抽象方法(只能定义方法起名字的规则)
  2. 类可以实现接口:使用implements关键字
  • 实现:接口中只有方法名称的定义,在类中把接口方法的真正完成逻辑写出来
class 类名称 implements 接口名称 {
		对接口中方法的实现;
}
  1. 接口的实例化:不能直接实例化
  • 定义实现类,实现接口,类创建对象,对象调用方法
  1. 接口的实现类:
  • 如果是一个抽象类,该类没有实现接口中的所有抽象方法
  • 如果是一个普通类,该类实现了接口中的所有抽象方法
public class Computers  {
    public static void main(String[] args) {
        //创建一个电脑对象
        Computer cm = new Computer();
        cm.start();
        //连键盘
        cm.useUSB(new Keyboard());
        //连鼠标
        cm.useUSB(new Mouse());
        cm.playGame();
        cm.shutdown();
    }
}

class Computer{
    //开机的方法
    public void start(){
        System.out.println("开机");
    }
    //关机的方法
    public void shutdown(){
        System.out.println("关机");

    }

    public void playGame(){
        System.out.println("开始打游戏");
    }
    //使用USB接口
    public void useUSB(USB u){//多态的一种体现
        u.use();
    }
}

interface USB {
    public abstract void use();
}

class Keyboard implements USB{
    //将键盘连到我们的USB接口上
    @Override
    public void use(){
        System.out.println("键盘已连接");

    }
}

class Mouse implements USB {
    //将鼠标连到我们的USB接口上
    @Override
    public void use() {
        System.out.println("鼠标已连接");
    }
}

运行结果为:

在这里插入图片描述
接口的作用:

  1. 约束
  2. 定义一些方法,让不同的人实现
  3. public abstract
  4. public static final
  5. 接口不能被实例化,接口中没有构造方法
  6. implements可以实现多个接口
  7. 必须要重写接口中的方法

六、内部类

6.1 内部类

在这里插入图片描述

6.1.1 成员内部类

(1)创建外部和内部类(外部类Outer,内部类Inner)

/**
 * 一个类中只有一个public class 类,但可以有多个class 类
 */
public class Outer {

   private int id = 10;

   public void outer(){

       System.out.println("外部成员类的方法");
   }
   public class Inner{

       public void in(){

           System.out.println("内部成员类的方法");
       }
       public void getId(){
           System.out.println(id);
       }
   }
}

(2)创建测试类

public class Application {

    public static void main(String[] args) {

        Outer outer = new Outer();

        Outer.Inner inner = outer.new Inner();

        inner.in();

        inner.getId();
    }
}

运行结果为:

在这里插入图片描述

6.1.2 静态内部类

静态内部类只需在上面public 后面加上static就可以,静态无法访问非静态。

6.1.3 局部内部类

public class JuBuNeiBuLei {

    public void ju(){

        System.out.println("成员");

        class A{

            //局部
        }
    }
}

6.1.4 匿名内部类

public class NiMing {

    public static void main(String[] args) {
        //没有名字初始化类,不用讲实例保存到变量中~
        new Apple().eat();//匿名
        
        new UserService(){

            @Override
            public void add() {
                
            }
        };
    }
}
class Apple{
    
    public void eat(){

        System.out.println("吃苹果");
    }
}
interface UserService{
    
    public void add();
}

运行结果为:

在这里插入图片描述

七、异常(了解)

7.1 异常概述

  1. 在java程序运行过程中,出现的不正常情况,出现的错误,称为异常
  2. 异常就是一个对象,描述那些不符合生活正常情况的异常情况,包含了这些情况的原因、类型、描述以及位置,这些内容都封装到异常对象中。
  3. 异常也是一种处理异常情况的机制,可以进行跳转、捕获以及结束程序

在这里插入图片描述

public class Exception_Daniel {

    public static void main(String[] args) {

        System.out.println(11/0);
    }
}

运行结果:

在这里插入图片描述

7.2 异常体系

  1. Throwable:可抛出的,是异常体系的顶层父类,其他的异常或者错误都是Throwable的子类类型,只有Throwable的体系类型,才可以使用异常的处理机制
  2. Error:错误,是Throwable的子类,用于描述那些无法捕获和处理的错误情况,属于非常严重的错误,StackOverflowError
  3. Exception:异常,是Throwable的子类,用于描述那些可以捕获和处理的例外情况,属于不太严重的错误,ArrayIndexOutOfBoundsException
  4. RuntimeException:运行时异常,是Exception的特殊的子类,在编译阶段不做检查的一个异常
  5. 体系图:
  • Throwable
    – Error
    — Exception
    — RuntimeException

在这里插入图片描述
在这里插入图片描述

在jvm中默认处理异常的机制

  1. 在代码的某个位置,出现了和正常情况不同的情况,就将异常情况封装到一个异常对象中。
  2. 将异常对象抛给调用该方法的方法
  3. 某个方法接收到底层方法抛上来的异常,也没有办法自己处理,继续向上抛出,最终抛给主方法,主方法也没有办法处理,抛给调用自己的jvm虚拟机
  4. Jvm虚拟机是我们手动调用的,只能将异常对象的所有信息,通过错误流打印出来,结束jvm虚拟机
  5. 总结,jvm默认处理的方式:【一层一层向上抛,jvm接收到之后结束自己】

ERROR
在这里插入图片描述
Exception
在这里插入图片描述

7.3 异常处理机制

在这里插入图片描述
异常解决:

public class TryCatch {

    public static void main(String[] args) {

        int a = 2;
        int b = 0;
        try {
            System.out.println(a/b);
        }catch (Exception e){
            System.out.println("程序出现异常了");
            //e.printStackTrace();
        }finally {
            System.out.println("不管咋样我都要执行");
        }
    }
}

运行结果为:

在这里插入图片描述

7.4 throw和throws的比较

  1. throw是对异常对象的抛出,throws是对异常类型的声明
  2. throw是对异常对象实实在在的抛出,一旦使用了throw关键字,就一定有一个异常对象出现;throws是对可能出现的异常类型的声明,即使声明了一些异常类型,在这个方法中,也可以不出现任何异常。
  3. throw后面只能跟一个异常对象;throws可以跟很多个异常类型

7.5 自定义异常

在这里插入图片描述

实际应用中的经验总结

在这里插入图片描述

计算年龄案例

package com.zql3;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Scanner;

/**
 * @author Daniel 
 * 已知生日算年龄
 */

public class Demo5 {
    public static void main(String[] args) throws ParseException {

        Scanner scanner = new Scanner ( System.in );
        System.out.println ("please input your birthday:ex:2022-05-01");
        String birthday = scanner.nextLine ();

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat ( "yyyy-MM-dd" );
        long time =  simpleDateFormat.parse ( birthday ).getTime ();
        long now = System.currentTimeMillis ();
        System.out.println ((now-time)/1000/3600/24/365);
        
    }
}

最终运行效果:

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Daniel521-Spark

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

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

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

打赏作者

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

抵扣说明:

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

余额充值