Java基础_Object类_异常

167 阅读10分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第31天,点击查看活动详情

01.Object类_概述

1).在Java类库中,有一个类叫:Object,它是Java中所有引用类型(包括数组、类中的类、我们定义的类)的公共基类。
2).我们定义的任何类,都隐式的继承自Object3).任何的引用数据类型都从Object继承了很多的方法,例如:equals(),toString()......
   这些方法被强制继承,任何引用类型都会拥有。它的好处:现有的一些类可以使用这些方法进行工作了,这种继承会保证
   任何类都有这些方法。
4).java.lang包下的类属于常用类,用的时候不需要导包,其它包下的类使用时就需要导包了。

02.Object类_数值比较和对象比较的说明

1).数值比较:使用"=="运算符,它可以比较两个值是否相同。
        int a = 10;
        int b = 20;
        System.out.println(a == b);//false
2).对象比较:两个对象之间有时也需要进行比较,通常是比较两个对象内的所有属性的值是否相同。
         两个对象的比较的方式有两种:
         1).使用"==":比较的两个对象的地址是否相同;
            Student stu1 = new Student();
            Student stu2 = new Student();
            System.out.println(stu1 == stu2);//false

            Student stu3 = stu1;
            System.out.println(stu1 == stu3);//true
         2).判断两个对象内部的所有属性值是否完全相同:
            假如:Student有三个属性:年龄(int age):性别(char sex):身高(double height):
            Student stu1 = new Student();
            stu1.age = 20;
            stu1.sex = '男';
            stu1.height = 1.75;

            Student stu2 = new Student();
            stu2.age = 20;
            stu2.sex = '男';
            stu2.height = 1.75;
            要比较这两个对象内部的属性值是否完全相同:
            System.out.println(stu1.age == stu2.age && stu1.sex == stu2.sex && stu1.height == stu2.height);

            但是,如果属性特别多,而且需要经常进行比较,每次都这样写,很费事,所以,我们最好封装一个方法。
        Object类定义了一个equals(),这个方法的作用就是用来:将"当前对象""参数对象"进行比较。我们如果需要
        经常的比较两个对象,可以重写这个方法,方法内部进行各个属性的比较,然后如果需要跟其它对象进行比较,就
        调用一下这个方法即可。
    String str1 = new String("abc");
    String str2 = new String("abc");
    System.out.println(str1 == str2);//false
    System.out.println(str1.equals(str2));//true--比较的内容

03.Object类_equals方法

1).equals()方法在Object类中定义,任何的引用类型都有这个方法,用于将当前对象与其它对象进行比较;
2).Object类中的equals()方法的默认实现:比较两个对象的地址是否相同,效果等同于==
   Java类库中的类有很多类已经重写了equals()方法,比如:Stringpublic class Object{
      public boolean equals(Object obj){
          //默认实现:等同于==运算符,比较两个对象的地址是否相同
         //建议:如果此对象有需求和其它对象进行比较,建议重写此方法
      }
  }
  class Student extends Object{
        //重写父类的equals
        public boolean equals(Object obj){
        }
  }
3).我们定义的类,如果需要跟其它同类对象进行比较,可以重写equals()方法。
4).怎样重写:在Eclipse下:
    shift + alt + s --> h (可以去掉hashCode()方法)

04.Object类_toString方法

1).toString()方法在Object类中定义,任何的引用类型都有这个方法,用于封装对象中所有属性的值;
2).Object类中的toString的默认实现:运行时对象的全名限定名 + @ + 十六进制地址
   Java类库中的类,基本上都重写的toString();
   我们的类也建议:重写toString()方法
   class Object{
      public String toString(){
          //默认实现:运行时对象的全名限定的类名+@+十六进制地址;
          //对我们来说无意义,建议重写此方法
      }
  }
  class Student extends Object{
        //重写toString-->打印所有属性值
        public String toString(){
            //将所有的属性值作为一个String返回;
        }
  }

05.异常_异常的概念演示

1).我们编写的代码都会有一些安全隐患,如果一旦发生问题,会导致JVM无法继续运行,此时
   JVM会在控制台抛出异常信息,然后将我们的程序结束(这是我们不想看到的)。
2).我们总是希望即使异常产生,我们的程序也可以进行一些补救,从而使我们的程序继续健康的运行下去。
3).Java提供了一种语法,可以"监控"一些代码的执行,如果发生了异常了,可以转到"之前预定义的"的一段代码中去执行,
   执行完后,会使程序继续运行下去,这种机制就是:异常处理机制;

06.异常_Java中异常的体系结构_分类

Throwable(所有异常、错误的根类)
   |--Error(错误):用于指示合理的应用程序不应该试图捕获的严重问题。
   |--Exception(异常):它指出了合理的应用程序想要捕获的条件。
      |--RuntimeException(运行时异常):指一些可以通过判断等方式避免的一些异常情况。比如:空指针异常(NullPointerException),数组下标越界异常(ArrayIndexOutOfBoundsException)
      |--除RuntimeException以外的其它异常(非运行时异常):无法通过判断避免的一些异常情况。程序中对这种异常要求必须监控,并捕获,防止程序因此终止。

07.异常_JVM默认处理异常的方式

1.JVM执行到有异常的代码:
    int i = 10 / 0;
2.JVM识别出这个异常;除0操作
3.到类库中找到这个异常所对应的"异常类":
4.将这个异常类创建一个对象;
5.将异常类名,异常信息,堆栈异常信息(代码中出现异常的位置)打印到控制台中;
6.将我们的程序终止。

08.异常_基本方式try_catch处理异常_过程解析

..之前的代码...
try{
    //可能出现异常的代码   
}catch(异常类型名 变量名){
    //如果try中出现了"异常类型名"的异常,将会执行这个catch中的语句
    //catch执行完毕,会继续执行try...catch...的后续语句,程序将会继续健康的运行下去。
}
..后续代码...
1.没有异常的执行顺序:
    1).之前的代码;
    2)try中的代码;
    3)后续代码
2.如果有异常执行顺序:
    1).之前的代码;
    2)try中的代码(如果有异常,立即停止try中的执行);
    3).跳到catch中执行(前提catch中的异常类型跟try中出现的异常是相同类型)
        4).后续代码....

09.异常_多catch处理异常_过程解析

..之前的代码...
try{
    //可能出现多种异常
}catch(异常类型1 变量名){

}catch(异常类型2 变量名){

}catch(异常类型3 变量名){

}....
..后续代码....
1.执行流程:只要try中出现异常,立即终止try的后续代码的执行,找到相应的catch()去执行,之后执行后续代码...
2.多个catch中的"异常类型"可以"同级别"的异常,没有前后顺序的关系。
  也可以是"子父级关系",父级的异常类型必须声明在多个catch的最后

10.异常_JDK7针对多个异常的处理方案

try{
    //可能出现异常的代码
}catch(异常类型1 | 异常类型2 | 异常类型3 变量名){
    //几种异常使用同一种方式处理
}
注意:多个异常类型不能有"父级"的异常。

11.异常_编译期异常和运行期异常的区别

1).运行时异常:指一些可以通过判断等方式避免的一些异常情况。比如:空指针异常(NullPointerException),数组下标越界异常(ArrayIndexOutOfBoundsException)
2).非运行时异常:无法通过判断避免的一些异常情况。程序中对这种异常要求必须监控,并捕获,防止程序因此终止。

12.异常_Throwable的几个常见方法

1).public String getMessage():获取异常信息
2).public String toString():异常类名 + ":" + 异常信息
3).public void printStackTrace():打印堆栈异常。
    格式:异常类名 : 异常信息
        at ....(异常的位置)
            .......
        .......

13.异常_方法中处理异常的方式_throws【常用】

public class ArrayTools{
    public static int sum(int[] arr) throws NullPointerException,
                        ArrayIndexOutOfBoundsException,
                        Exception{
        int sum = 0;
        for(int n : arr){
            sum += n;
        }
        return sum;
    }
}
1).在方法中可以正常编写代码,然后将可能抛出的异常声明到方法定义的位置--方法的形参列表之后
2).可以同时声明抛出多个异常,中间用逗号隔开,而且可以是子父级关系,而且没有顺序关系。
3).声明抛出的是:
    1).运行时异常:调用处可以不处理(不使用try...catch...或者也不抛出),如果不处理,出现异常,程序仍然是挂掉。
    2).非运行时异常:调用处必须处理,要么try...catch...,要么继续抛出。

14.异常_方法中处理异常的方式_throw

public class ArrayTools{
    public static int getMax(int[] arr){
        if(arr == null){
            //这时,就需要告诉调用处,这里出异常了
            throw new NullPointerException("空指针异常!");//执行到这里,方法会立即返回,不会向下执行了。
        }
        if(arr.length == 0){
            throw new ArrayIndexOutOfBoundsException("你传递了一个0长度的数组!!");
        }
        int max = arr[0];
        for(int n : arr){
            max = n > max ? n : max;
        }
        return max;
    }
}
1).throw表示"手动的抛出一个异常对象";
2).用在方法体内,后面只能跟"异常对象",只能是一个异常对象。
3).抛出的是:
    1).运行时异常:方法声明处可以不显示的声明throws抛出此异常,调用处也可以不处理;
    2).非运行时异常:方法声明处必须显示的使用throws声明抛出此异常,调用处必须处理(要么try..catch...,要么继续抛出)

15.异常_try...catch...finally处理异常_过程解析

try{
    ...
}catch(...){
    ...
}finally{
    //无论是否出现异常,都会被执行的代码
}
1).在finally中,经常用于释放资源;
例如:
    public static String readFile() throws IOException {
        BufferedReader in = null;
        try{
            in = new BufferedReader(new FileReader("demo10.txt"));
            String row = in.readLine();
            return row;//会在return前执行finally
        }catch(IOException e){
            throw e;   //会在throw前执行finally
        }finally{
            if(in != null){
                in.close();
            }
        }
    }

16.异常_面试题之如果在finally之前有return

class Test{
    public static void main(String[] args){
        System.out.println(fun());//20
    }
    public static int fun(){
        int n = 10;
        try{
            n = 20;
            int i = 10 / 0;
            return n;//1.将n的值20缓存起来;2).执行finally(n = 40) 3).回来将之前缓存的值20返回;
        }catch(Exception e){
            n = 30;
            return n;//30
        }finally{
            n = 40;
            return n;// 会出警告线(不建议在finally中使用return),这个return会返回:40
        }
    }
}

17.异常_自定义异常概述

class Student{
    private int age;
    public void setAge(int age){
        if(age < 15 || age > 50){
            throw 什么异常?我们可以自己定义异常
        }
        this.age = age;
    }
}

18.异常_自定义异常的实现和测试

1).自定义异常:
    A).自定义异常类,继承自Exception或者它的某个子类
        class AgeException extends Exception{//如果继承Exception,属于:非运行时异常。如果继承RuntimeException,属性运行时异常。
            public AgeException(String msg){//用于指定异常消息的构造方法
                super(msg);
            }
        }
    B).使用自定义异常:
        public class Student {
            private int age;
            public void setAge(int age) throws AgeException {
                if(age < 15 || age > 50){
                    throw new AgeException("年龄要在15到50之间!");
                }
                this.age = age;
            }
        }
    C).前端调用处:
        Student stu = new Student();
        try {
            stu.setAge(20);
        } catch (AgeException e) {
            System.out.println("异常了,异常信息是:" + e.getMessage());
        }

19.异常_子类重写父类方法时的异常声明

class Fu{
    public void show() throws IOException{
    }
}
class Zi extends Fu{
    public void show() throws IOException {
    }
}

1.父类方法不抛出任何异常:
    1).子类可以不抛出任何异常;
    2).子类可以抛出任何的运行时异常;
    3).子类不能抛出任何的非运行时异常;
2.父类方法抛出运行时异常:
    1).子类可以不抛出任何异常;
    2).子类可以抛出任何的运行时异常;
    3).子类不能抛出任何的非运行时异常;
3.父类方法抛出非运行时异常:
    1).子类可以不抛出任何异常;
    2).可以可以抛出任何的运行时异常;
    3).子类只能抛出跟父类相同的非运行时异常,不能抛出更多的非运行时异常。


无论父类抛出什么异常,子类都可以:不抛出任何异常;也可以抛出任何的运行时异常;同时不能抛出比父类更多的非运行时异常。