Java笔记-List,Set,Map介绍,Exception

一 集合

1.1集合简介

    集合是java中提供的一种容器,可以用来存储多个数据。
    在前面的学习中,我们知道数据多了,可以使用数组存放或者使用ArrayList集合进行存放数据。那么,集合和数组既然都是容器,它们有啥区别呢?
    区别①:数组的长度是固定的;集合的长度是可变的。

    区别②:集合中存储的元素必须是引用类型数据。

集合继承关系图:

      a:ArrayList的继承关系:
     查看ArrayList类发现它继承了抽象类AbstractList同时实现接口List,而List接口又继承了Collection接口。Collection接口为最顶层集合接口了。
     源代码:
      interface List extends Collection {
      }
      public class ArrayList extends AbstractList implements List{
      }
    
     b:集合继承体系
     这说明我们在使用ArrayList类时,该类已经把所有抽象方法进行了重写。那么,实现Collection接口的所有子类都会进行方法重写。
          Collecton接口常用的子接口有:List接口、Set接口
          List接口常用的子类有:ArrayList类、LinkedList类
          Set接口常用的子类有:HashSet类、LinkedHashSet类
     
                                    Collection 接口     
                                             |
     ---------------------------------------------------------
        |                                                                       |
    List接口                                                            Set接口
        |                                                                      |
   ----------------                                                -------------
   |                         |                                             |                     |

ArrayList类    LinkedList类                         HashSet类     LinkedHashSet类

1.2集合Collection介绍

Collection接口中的方法,是集合中所有实现类必须拥有的方法,使用Collection接口的实现类。方法的执行,都是实现的重写。
      *  ArrayList implements List

      *  List extends Collection

学习Java中三种长度表现形式:
       *   数组.length 属性  返回值 int
       *   字符串.length() 方法,返回值int
       *   集合.size()方法, 返回值int

Collection接口方法
       *  Object[] toArray() 集合中的元素,转成一个数组中的元素, 集合转成数组
       *  返回是一个存储对象的数组, 数组存储的数据类型是Object

       * boolean contains(Object o) 判断对象是否存在于集合中,对象存在返回true
       * 方法参数是Object类型

       * void clear() 清空集合中的所有元素
       * 集合容器本身依然存在

       *boolean remove(Object o)移除集合中指定的元素

1.3迭代器

   a:Java中提供了很多个集合,它们在存储元素时,采用的存储方式不同。
    我们要取出这些集合中的元素,可通过一种通用的获取方式来完成。  
   b:Collection集合元素的通用获取方式:在取元素之前先要判断集合中有没有元素,
  如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。 
   c:每种集合的底层的数据结构不同,例如ArrayList是数组,LinkedList底层是链表,但是无论使用那种集合,我们都会有判断是否有元素以及取出里面的元素的动作,那么Java为我们提供一个迭代器定义了统一的判断元素和取元素的方法

迭代器的实现原理
    集合中的迭代器获取集合中元素方式
     *  接口 Iterator : 两个抽象方法
     *     boolean hasNext() 判断集合中还有没有可以被取出的元素,如果有返回true
     *     next() 取出集合中的下一个元素
    Iterator接口,找实现类.
     *    Collection接口定义方法
     *       Iterator  iterator()
     *    ArrayList 重写方法 iterator(),返回了Iterator接口的实现类的对象
     *    使用ArrayList集合的对象
     *     Iterator it =array.iterator(),运行结果就是Iterator接口的实现类的对象
     *     it是接口的实现类对象,调用方法 hasNext 和 next 集合元素迭代
     */

迭代器的代码实现
          Collection<String> coll = new ArrayList<String>();
          coll.add("abc1");
          coll.add("abc2");
          //迭代器,对集合ArrayList中的元素进行取出    
          //调用集合的方法iterator()获取出,Iterator接口的实现类的对象
          Iterator<String> it = coll.iterator();
          //接口实现类对象,调用方法hasNext()判断集合中是否有元素
          //迭代是反复内容,使用循环实现,循环的条件,集合中没元素, hasNext()返回了false
          while(it.hasNext()){
            String s = it.next();
            System.out.println(s);
          }

        //for循环迭代写法:
        for ( Iterator<String> it2 = coll.iterator(); it2.hasNext();  ) {
           System.out.println(it2.next());

       }

1.4增强for循环

   *增强for循环遍历数组:好处: 代码少了,方便对容器遍历;弊端: 没有索引,不能操作容器里面的元素
      *  JDK1.5新特性,增强for循环
      *  JDK1.5版本后,出现新的接口 java.lang.Iterable
      *    Collection开始继承Iterable
      *    Iterable作用,实现增强for循环  
     public static void function_1(){
        //for对数组遍历
        String[] str = {"abc","itcast","cn"};
        for(String s : str){
          System.out.println(s.length());
        }
      }
   *增强for循环遍历集合 
        public static void function_2(){
          ArrayList<Person> array = new ArrayList<Person>();
          array.add(new Person("a",20));
          array.add(new Person("b",10));
          for(Person p : array){
            System.out.println(p);
          }
        }

1.5泛型的定义和使用

     *   JDK1.5 出现新的安全机制,保证程序的安全性
     *   泛型: 指明了集合中存储数据的类型  <数据类型>
        Collection<String> coll = new ArrayList<String>();
        coll.add("abc");
        coll.add("rtyg");
        coll.add("43rt5yhju");       
        Iterator<String> it = coll.iterator();
        while(it.hasNext()){
          String s = it.next();
          System.out.println(s.length());

        }

*Java中的伪泛型:泛型只在编译时存在,编译后就被擦除,在编译之前我们就可以限制集合的类型,起到作用。

     例如:ArrayList<String> al=new ArrayList<String>();
     在编译后:ArrayList al=new ArrayList();

* 泛型的好处
     a:将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
     b:避免了类型强转的麻烦。

*  泛型的通配,匹配所有的数据类型:  ? 

    下面的例子,子类拥有共同的父类,并都重写了父类work()方法

     * ? 通配符,迭代器it.next()方法取出来的是Object类型,怎么调用work方法
     * 强制转换:  it.next()=Object o ==> Employee
     * 方法参数: 控制,可以传递Employee对象,也可以传递Employee的子类的对象
     * 泛型的限定  本案例,父类固定Employee,但是子类可以无限?
     *   ? extends Employee 限制的是父类, 上限限定, 可以传递Employee,传递他的子类对象
     *   ? super   Employee 限制的是子类, 下限限定, 可以传递Employee,传递他的父类对象
     */
    public static void iterator(ArrayList<? extends Employee> array){     
       Iterator<? extends Employee> it = array.iterator();
       while(it.hasNext()){
         //获取出的next() 数据类型,是什么Employee

         Employee e = it.next();

        //调用子类重写后的方法

         e.work();
       }
    }

//然后在主方法中调用即可

//创建3个集合对象
      ArrayList<ChuShi> cs = new ArrayList<ChuShi>();
      ArrayList<FuWuYuan> fwy = new ArrayList<FuWuYuan>();
      ArrayList<JingLi> jl = new ArrayList<JingLi>();     
      //每个集合存储自己的元素
      cs.add(new ChuShi("张三", "后厨001"));
      cs.add(new ChuShi("李四", "后厨002"));     
      fwy.add(new FuWuYuan("翠花", "服务部001"));
      fwy.add(new FuWuYuan("酸菜", "服务部002"));     
      jl.add(new JingLi("小名", "董事会001", 123456789.32));
      jl.add(new JingLi("小强", "董事会002", 123456789.33));
//调用方法上面iterator()
      iterator(jl);
      iterator(fwy);
      iterator(cs);

二 List接口介绍

2.1接口介绍及常用方法

List接口:

        它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照11、22、33的顺序完成的)。

        它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。

        集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

List接口的常用子类有:

        ArrayList集合:ArrayList集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList是最常用的集合。

        LinkedList集合:LinkedList集合数据存储的结构是链表结构。方便元素添加、删除的集合。实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法。在开发时,LinkedList集合也可以作为堆栈,队列的结构使用。常用方法如下:

        

List接口中常用方法:

    增加元素方法

        add(Object e):向集合末尾处,添加指定的元素

        add(int index, Object e):向集合指定索引处,添加指定的元素,原有元素依次后移

    删除元素删除

        remove(Object e):将指定元素对象,从集合中删除,返回值为被删除的元素

        remove(int index):将指定索引处的元素,从集合中删除,返回值为被删除的元素

    替换元素方法

        set(int index, Object e):将指定索引处的元素,替换成指定的元素,返回值为替换前的元素

    查询元素方法

        get(int index):获取指定索引处的元素,并返回该元素

    获取长度方法:size()

    注意:List遍历方式有三种:普通for循环;迭代器Iterator;增强for循环

2.2 Iterator的并发修改异常

        Iterator<String> it = list.iterator();

        while(it.hasNext()){

            String str = it.next();

            //判断取出的元素是否是"abc2",是就添加一个新元素

            if("abc2".equals(str)){

                list.add("itcast");// 该操作会导致程序出错

            }

        }

    运行上述代码发生了错误java.util.ConcurrentModificationException(并发修改异常)这是什么原因呢?

    在迭代过程中,使用了集合的方法对元素进行操作。导致迭代器并不知道集合中的变化,容易引发数据的不确定性。

    并发修改异常解决办法:在迭代时,不要使用集合的方法操作元素。

    那么想要在迭代时对元素操作咋办?通过ListIterator迭代器操作元素是可以的,ListIterator的出现,解决了使用Iterator迭代过程中可能会发生的错误情况。

2.3List集合存储数据的结构

    List接口下有很多个集合,它们存储元素所采用的结构方式是不同的,这样就导致了这些集合有它们各自的特点,供给我们在不同的环境下进行使用。数据存储的常用结构有:堆栈、队列、数组、链表。我们分别来了解一下:

①堆栈,采用该结构的集合,对元素的存取有如下的特点:

    先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。

    栈的入口、出口的都是栈的顶端位置

    压栈:就是存元素。即,把元素存储到栈的顶端位置,栈中已有元素依次向栈底方向移动一个位置。

    弹栈:就是取元素。即,把栈的顶端位置元素取出,栈中已有元素依次向栈顶方向移动一个位置。

②队列,采用该结构的集合,对元素的存取有如下的特点:

    先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,安检。排成一列,每个人依次检查,只有前面的人全部检查完毕后,才能排到当前的人进行检查。

    队列的入口、出口各占一侧。

③数组,采用该结构的集合,对元素的存取有如下的特点:

    查找元素:通过索引,可以快速访问指定位置的元素

    增删元素

        指定索引位置增加元素:需要创建一个新数组,将指定新元素存储在指定索引位置,再把原数组元素根据索引,复制到新数组对应索引的位置。

        指定索引位置删除元素:需要创建一个新数组,把原数组元素根据索引,复制到新数组对应索引的位置,原数组中指定索引位置元素不复制到新数组中。

④链表,采用该结构的集合,对元素的存取有如下的特点:

    多个节点之间,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。

    查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素

    增删元素快:

        增加元素:操作如左图,只需要修改连接下个元素的地址即可。

        删除元素:操作如右图,只需要修改连接下个元素的地址即可。

        

2.4 Vector集合

    Vector集合数据存储的结构是数组结构,为JDK中最早提供的集合。Vector中提供了一个独特的取出方式,就是枚举Enumeration,它其实就是早期的迭代器。此接口Enumeration的功能与 Iterator 接口的功能是类似的。Vector集合已被ArrayList替代。枚举Enumeration已被迭代器Iterator替代。

    Vector集合对ArrayList集合使用的对比


三 Set接口

    List中是可以存放重复元素的。那么不重复元素给哪里存放呢?那就是Set接口,它里面的集合,所存储的元素就是不重复的。通过元素的equals方法,来判断是否为重复元素

3.1 HashSet集合介绍

    此类实现Set接口,由哈希表支持(实际上是一个HashMap集合)。HashSet集合不能保证的迭代顺序与元素存储顺序相同。

HashSet集合,采用哈希表结构存储数据,保证元素唯一性的方式依赖于:hashCode()equals()方法。

3.2 HashSet集合存储数据的结构(哈希表)

什么是哈希表呢?

    哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表

    当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

    总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。


3.3 HashSet存储JavaAPI中的类型元素以及自定义类型元素

    给HashSet中存储JavaAPI中提供的类型元素时,不需要重写元素的hashCode和equals方法,因为这两个方法,在JavaAPI的每个类中已经重写完毕,如String类、Integer类等。

    给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一。如下例子:这些函数都可以自动生成

        

3.4LinkedHashSet介绍

    我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办呢?

    在HashSet下面有一个子类LinkedHashSet,它是链表和哈希表组合的一个数据存储结构。

判断集合元素唯一的原理

①ArrayList的contains方法判断元素是否重复原理

   

    ArrayList的contains方法会使用调用方法时,传入的元素的equals方法依次与集合中的旧元素所比较,从而根据返回的布尔值判断是否有重复元素。此时,当ArrayList存放自定义类型时,由于自定义类型在未重写equals方法前,判断是否重复的依据是地址值,所以如果想根据内容判断是否为重复元素,需要重写元素的equals方法。

②HashSet的add/contains等方法判断元素是否重复原理

    

    Set集合不能存放重复元素,其添加方法在添加时会判断是否有重复元素,有重复不添加,没重复则添加。

    HashSet集合由于是无序的,其判断唯一的依据是元素类型的hashCode与equals方法的返回结果。规则如下:

        先判断新元素与集合内已经有的旧元素的HashCode值

            如果不同,说明是不同元素,添加到集合;

            如果相同,再判断equals比较结果。返回true则相同元素;返回false则不同元素,添加到集合。

    所以,使用HashSet存储自定义类型,如果没有重写该类的hashCode与equals方法,则判断重复时,使用的是地址值,如果想通过内容比较元素是否相同,需要重写该元素类的hashcode与equals方法

3.5总结

 ①* 问题:两个对象 Person p1 p2,如果两个对象的哈希值相同p1.hashCode()==p2.hashCode()

那么两个对象的equals一定返回true吗??即p1.equals(p2)返回true吗?

 * 答:  不一定!       

 * 问题:如果两个对象的equals方法返回true,p1.equals(p2)==true

 *            两个对象的哈希值一定相同吗??

 * 答:  一定!!这是由hashCode官方定义给出的,API如下:


②List与Set集合的区别?

    List: 它是一个有序的集合(元素存与取的顺序相同)

           它可以存储重复的元素                         

    Set: 它是一个无序的集合(元素存与取的顺序可能不同)

           它不能存储重复的元素

    ArrayList:  底层数据结构是数组,查询快,增删慢

    LinkedList:底层数据结构是链表,查询慢,增删快

    HashSet:  元素唯一,不能重复

                    底层结构是 哈希表结构

                    元素的存与取的顺序不能保证一致

                    如何保证元素的唯一的?

                        重写hashCode() equals()方法(使用到集合存储数据时,就要重写)

    LinkedHashSet:元素唯一不能重复

                底层结构是 哈希表结构 + 链表结构

                元素的存与取的顺序一致

四 Map接口

4.1 Map接口概述

    我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同。

    Collection中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。

    Collection中的集合称为单列集合,Map中的集合称为双列集合。需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。

    Map中常用的集合为HashMap集合、LinkedHashMap集合。

    HashMap<K,V>:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法

    LinkedHashMap<K,V> HashMap 下有个子类 LinkedHashMap ,存储数据采用的哈希表结构 + 链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的 hashCode()方法、equals() 方法

4.2 Map接口中的常用方法

    put方法:将指定的键与值对应起来,并添加到集合中。方法返回值为键所对应的值

        使用put方法时,若指定的键(key)在集合中没有,则没有这个键对应的值,返回null,并把指定的键值添加到集合中;

        使用put方法时,若指定的键(key)在集合中存在,则返回key原来的value值,并把指定键所对应的值替换成指定的新值。

    get方法:获取指定键(key)所对应的值(value)

    remove方法:根据指定的键(key)删除元素,返回被删除元素的值(value)。

4.3 Map集合遍历

①根据键找值

    键找值方式:即通过元素中的键,获取键所对应的值。使用keySet()方法

    操作步骤:

        1.keySet()方法获取Map集合中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键

        2.遍历键的Set集合,得到每一个键

        3.根据键,用get(Object key)获取键所对应的值

        

②Entry键值对对象

    在Map类设计时,提供了一个嵌套接口:Entry。Entry将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值。

    键值对方式:即通过集合中每个键值对(Entry)对象,获取键值对(Entry)对象中的键与值。

    操作步骤:

         1.entrySet()方法获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。

         2.遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象getKey()方法

         3.通过键值对(Entry)对象, getValue()方法获取Entry对象中的键与值。

        

在导包的过程中我们可以直接导入静态部分,这样某个类的静态成员就可以直接使用了。在源码中经常会出现静态导入。

静态导入格式:import static XXX.YYY;   导入后YYY可直接使用。

例如:Map.Entry的访问,简化后为Entry

        

4.4 Hashtable

Hashtable: Map接口实现类

        底层结构数据哈希表,特点等和HashMap是一样的

        HashMap线程不安全集合,运行速度快

        Hashtable线程安全集合,运行速度慢

Hashtable命运和Vector一样,从JDK1.2开始,被更先进的HashMap取代

注意不同点: HashMap允许存储null值,null键;Hashtable不允许存储null值,null键

4.5可变参数

    在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化成如下格式:

            修饰符返回值类型方法名(参数类型...形参名){  }

    其实上面这个书写完全等价与

            修饰符返回值类型方法名(参数类型[] 形参名){  }

    只是后面这种定义,在调用时必须传递数组,而前者可以直接传递数据即可。

    jdk1.5以后。出现了简化操作。...用在参数上,称之为可变参数。

    同样是代表数组,但是在调用这个带有可变参数的方法时,不用创建数组(这就是简单之处),直接将数组中的元素作为实际参数进行传递,其实编译成的class文件,将这些元素先封装到一个数组中,在进行传递。这些动作都在编译.class文件时,自动完成了。

        

    上述add方法在同一个类中,只能存在一个。因为会发生调用的不确定性

    注意:如果在方法书写时,这个方法拥有多参数,参数中包含可变参数,可变参数一定要写在参数列表的末尾位置。

4.6集合继承体系的面向对象思想


接口:用来明确所有集合中该具有的功能,相当于在定义集合功能标准;

抽象类:把多个集合中功能实现方式相同的方法,抽取到抽象类实现,具体集合不再遍写,继承使用即可;

具体类:继承抽象类,实现接口,重写所有抽象方法,达到具备指定功能的集合。每个具体集合类,根据自身的数据存储结构方式,对接口中的功能方法,进行不同方式的实现。

4.7总结

HashMap特点:

        是Map集合的子集合

        底层采用哈希表结构

        HashMap集合中的key不能重复,通过重写hashCode() 与 equals()方法来保证键的唯一。

        不能保证元素存与取的顺序完全一致

LinkedHashMap特点:

        是HashMap集合的子集合

        底层采用哈希表+链表结构

        LinkedHashMap集合中的key不能重复,通过重写hashCode() 与 equals()方法来保证键的唯一。

 Collections中的方法:

        publicstatic <T> void sort(List<T> list) 排序

        publicstatic void shuffle(List<?> list) 集合中的元素存储位置随机打乱

五 异常

异常:就是程序中出现的不正常的现象(错误与异常)

异常的继承体系:

            Throwable:它是所有错误与异常的超类(祖宗类)

                    |----Error 错误,修改java源代码

                    |----Exception 编译期异常, javac.exe进行编译的时候报错

                                |----RuntimeException 运行期异常, java出现运行过程中出现的问题

异常处理的两种方式:

    1,出现问题,自己解决 try…catch…finally

        try{

            可能出现异常的代码

        }catch(异常类名  对象名){

            异常处理代码

        }finally {

            异常操作中一定要执行的代码

        }

    2,出现问题,别人解决 throws

        格式: 修饰符返回值类型方法名(参数) throws 异常类名1,异常类名2,...{}

        public  void  method()  throws  Exception {}

异常分类

    异常的根类是Throwable,其下有两个子类:Error与Exception,平常所说的异常指Exception。

        严重错误Error,无法通过处理的错误

        编译时异常Exception,编译时无法编译通过。如日期格式化异常

        运行时异常RuntimeException,是Exception的子类,运行时可能会报错,可以不处理。如空指针异常

异常基本操作

    创建异常对象

    抛出异常

    处理异常:①捕获处理,将异常获取,使用try/catch做分支处理

                    try{

                            需要检测的异常;

                    }  catch(异常对象) {

                           通常我们只使用一个方法:printStackTrace打印异常信息

                    }

                    ②声明抛出处理,出现异常后不处理,声明抛出给调用者处理。

                   方法声明上加throws  异常类名

    注意:异常的处理,指处理异常的一种可能性,即有了异常处理的代码,不一定会产生异常。如果没有产生异常,则代码正常执行,如果产生了异常,则中断当前执行代码,执行异常处理代码。

异常注意事项

    多异常处理

        捕获处理:

               1多个异常可以分别处理

               2多个异常一次捕获多次处理

               3多个异常一次捕获,采用同一种方式处理

        声明抛出异常:

               声明上使用,一次声明多个异常 

注意:运行时异常被抛出可以不处理。即不捕获也不声明抛出

        如果父类抛出了多个异常,子类覆盖父类方法时,只能抛出相同的异常或者是他的子集

        父类方法没有抛出异常,子类覆盖父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不能声明抛出

        当多异常处理时,捕获处理,前边的类不能是后边类的父类

自定义异常

    如果Java没有提供你需要的异常,则可以自定义异常类。

    定义方法:编译时异常继承Exception,运行时异常继承RuntimeException。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值