JavaSE复习_7 异常

△子父类涉及的异常问题:

     1.子类在覆盖方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类,且只能抛出异常的子集

     2.如果父类抛出了多个异常,子类只能抛出父类异常的子集,如果父类的方法没有抛出异常,那么子类重写方法时一定不能抛,只能捕捉

△throw和throws:

     1.throw声明在方法内部,抛出的是异常的对象。

     2.throws生命在方法上,抛出的是异常类

△编译异常和运行时异常:编译异常必须对其进行处理,而运行时异常不需处理.编译时的异常称为已检查异常,运行时的异常称为未检查异常。

△JDK1.7新增异常的特性:catch(Exception | NullpointerException e):捕获异常,这里注意,参数名只有一个,另外中间只能用"|"不能用"||".并且两个异常不能互相是继承关系。

△多catch语句,父类异常一定要放在最下面。

在一个异常体系捕捉后,catch语句块里面抛出另外一个异常是相当实用的做法。称为异常的转换。

△finally就算碰到return也会继续执行

△finally只用于发生异常且未捕捉到的时候,执行关闭资源的动作,其他情况下,其语句等同于正常的语句,按照正常的顺序执行。

△finally的返回值会将try语句的返回值覆盖

public static int f(int n){
               try{
                      int r =n *n ;
                      return r ;
              }
               finally{
                      if(n ==2)
                            return 6;
              }
       }

该语句当n=2时,返回6。

△try finally语句中,finally语句中如果关闭抛出了异常,那么后抛出的异常将会把刚抛出的异常给覆盖

class XyyException extends Exception{
        public XyyException(String s ){
               super(s );
       }
}
class HlhException extends Exception{
        public HlhException(String s ){
               super(s );
       }
}
public class Demo {

        public static void main(String[] args) throws XyyException, HlhException {
               f();
       }

        public static void f() throws XyyException, HlhException {
               int x =2;
               try{
                      x= x*2;
                      throw new XyyException("try");
              }
               finally{
                      if(x ==4){
                            throw new HlhException("finally");
                     }
              }
       }

}

异常为:

Exception in thread "main" string.Demo.HlhException: finally
       at string.Demo.Demo.f( Demo.java:26)
       at string.Demo.Demo.main( Demo.java:15)

解决这种方法的步骤为:采用带资源的try语句,在try()括号里实现了AutoCloseable接口的类都可以在调用try后关闭资源,(此时try语句里的资源关闭发生的异常将会被抑制,不会被抛出)。

△关于异常finally对于返回值的覆盖,有以下几点细节:

  finally语句在return执行后返回前执行。对于基本类型,return可以确定的是进入finally前的返回值。对于引用数据类型,return可以确定的是返回的对象内容。用两个示例加以说明:

public static int f(){
            int x=10;
       try{
        System.out.println(12/0);
        return x;
       } catch(Exception e) {
        x=20;
        return x;
       }
       finally {
        x=30;
        if(x==30)
              return x;
       }
}

  这个代码finally会将return30,因为finally中的return会将catch中的return覆盖,而如果没有return x,则该方法返回20,因为x仅仅赋值,但是返回的此时已经确定好了值.即在finally语句在return执行后返回前执行。

import java.util.*;

public class FinallyTest6
{
    public static void main(String[] args) {
        System.out.println(getMap().get("KEY").toString());
    }

    public static Map<String, String> getMap() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("KEY", "INIT");

        try {
            map.put("KEY", "TRY");
            return map;
        }
        catch (Exception e) {
            map.put("KEY", "CATCH");
        }
        finally {
            map.put("KEY", "FINALLY");
            map = null;
        }

        return map;
    }
}

  这个代码运行结果是finally。因为在try中即返回了引用所指向的对象(即确定的是对象),随后对对象的操作都会改变返回值,但是在finally代码块的最后一句将引用指向空,对于对象不构成任何影响,原对象返回。

△断言机制:assert关键字

格式为:assert 条件;

或assert 条件:表达式;(表达式部分的唯一目的是产生一个消息字符串。)

当assert的条件为false的时候,将会抛出一个有关键字构成的AssertionError异常。

利用java -ea打开assert,即可进入断言机制模式,默认情况下为关闭。

△记录日志

Logger logger=Logger.getLogger("Demo");               //获得一个记录器,其名为Demo

logger.setLevel(Level.ALL)                                        //获得记录器的等级

然后利用;logger.entering() logger.exiting记录进入方法,离开方法。(需要手动记录)

处理器:可以利用FileHandler将日志输出到文件。

FileHandler fh=new FileHandler( "MyLogger.txt");

fh.setLevel(Level. FINE);

logger .addHandler(fh);                 //将处理器添加到日志记录器中,可以添加多个

但是这样输出的文件将会是XML格式,不方便阅读因此需要定义格式化器,然后将其添加到处理器

示例:

package io.project.one;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;

public class Demo2 {
        public static void main(String[] args) {
              Logger logger=Logger. getLogger("io.project.one.Demo2");
               logger.setLevel(Level. FINE);
               try {
                     FileHandler fh= new FileHandler("MyLogger.txt" );
                      fh.setLevel(Level. FINE);
                      fh.setFormatter( new MyFormatter());
                      logger.addHandler( fh);

                      logger.fine( "进入main函数" );
                      int x =2;
                      int y =3;
                      add(x,y);
                      logger.exiting( "io.project.one.Demo2", "main" );
              } catch (Exception e ) {
                      e.printStackTrace();
              }
       }

        public static void add(int x, int y) {
              Logger logger=Logger. getLogger("io.project.one.Demo2");
               logger.fine( "io.project.one.Demo2");
              System. out.println("x+y" );
               logger.fine( "io.project.one.Demo2");
       }

}
class MyFormatter extends Formatter{

        @Override
        public String format(LogRecord record ) {
               return "类别:" +record .getLevel()+"....信息:"+ record.getMessage();
       }
}

这样输出的信息:

类别:FINE....信息:进入main函数类别:FINE....信息:io.project.one.Demo2类别:FINE....信息:io.project.one.Demo2。

简单易懂。

△小小的调试技巧

step into:跟踪到每个方法的内部

step over:定位到下一行,不跟踪到方法的内部。

△通过注释规避编译器检查

规避对于方法所有代码的检查:

@SuppressWarnings("unchecked" )

public void setFirst(T first) {

this.first = first ;

}

对于调用方法时的语句进行规避检查:

@SuppressWarnings("unchecked" )

Pair<String> mm=ArrayAlg. minmax(words);

时间: 2024-10-25 21:58:51

JavaSE复习_7 异常的相关文章

JAVASE复习

top 暑假每天中午更新 六花酱赛高 目录: 内部类 枚举类 垃圾回收 修饰符 与运行环境交互 内部类: 1. 外部类可以通过非静态内部类对象访问内部类的private属性,内部类可以直接访问外部类的private属性,说明外部类和内部类都是在“一个类中”,这样才能相互访问到对方的private属性 2. 非静态内部类的实例化:new Outer().new Inner();//这个很好理解,Inner需要用outer对象来实例化,Inner的命名空间是Outer 3. 静态内部类的实例化: n

javaSE复习之&mdash;&mdash;线程

线程其实就是程序执行的一条路径,一个进程中可以包含多条线程,多线程并发执行可以提高程序效率,可以同使完成多项任务 多线程的应用场景 迅雷多线程一起下载 服务器同时处理多个客户请求 多线程原理(单核CPU) 在电脑上运行多个程序时,其实cpu一次只能做一个事,做一段时间后然后换另一个另一个做一段时间,只是cpu的速度太快了,看起来就是同时做很多事,也就是说多线程其实只是表面上的多线程,底层cpu还是一次只能做一个事,但是这有个前提,那就是那个cpu是单核cpu,如果事多核cpu,那么就可以真正的达

个人JAVASE复习笔记

集合 6.28 Arraylist 使用迭代器遍历的时候不能操作  目标 (改变集合元素的个数)除非特有方法,迭代器中提供的方法 其他遍历正在进行时也  尽量不要去操作目标,容易出错 java.util.ConcurrentModificationException (并发修改异常) 中途了解 迭代器 原理以及源码 个人解决  使用了 toArray() 转成 数组操作 (也许以后有更好的方法 期待) 6.29因此 了解到了  并发容器 COW , 6.30还有 线程安全的List list =

JavaSE复习总结之集合(Collection)

Java早期版本只给集合类库提供了很少的一组类,但是随着Java版本的升级,Java集合类库越来越充实.集合类库里面存放的,是各式各样的数据容器,我们基本都学过数据结构这门课,数据结构所讲的就是ADT(抽象数据模型)的部分,数据结构不是针对于某一门语言,它所讲的通常是对各语言都通用的ADT部分,ADT和具体实现是没有关系的.但是根据教材.根据各专业的不同,各专业会选用使用不同编程语言实现的教材.而我们所讲的,就是如何使用Java数据容器,即Java集合(用Java实现的ADT),具体的实现部分,

JavaSE 复习

这里分享一下学JavaSE 用的教材 高宏静的 <Java从入门到精通>,每一章都是一个单独的PDF用来复习JavaSE该是够了. 链接: http://pan.baidu.com/s/1ntyrDMx 密码: 6htz

JavaSE复习日记 : 多态

/** * 里氏替换原则 : * 能使用父类的地方,一定可以使用子类 * 什么是多态 : * 父类的引用,指向子类的对象 * 多态的前提条件 : * 有继承关系的两个类 * 多态的目的 : * ☆☆☆ 代码的重用 * 多态发什么在什么时候 : * 赋值的时候 * * !!!!!!!!! 多态中的 ☆☆☆ 覆写 是特指的 成员方法!!!!!!!!! * 什么是覆写 : * 就是在子类有个和父类相同的方法 : 方法名 , 参数列表 , 返回值类型 (和修饰符列表没关系) * 1 方法名相同 : 不相

JavaSE复习_10 多线程复习

△wait()和sleep()的区别:  1.wait():没有等待时间,而sleep()需要有等待时间作为参数.  2.在同步中对于CPU的执行权和锁的处理不同:   wait()会释放执行权和锁.醒来后需要重新竞争锁.   sleep():释放执行权和,不会释放锁 void show(){ Synchronized(this){ wait() //可以同时有三个线程在此等待.只有拿到锁后,才能继续向下运行 } } void start(){ notifyAll(); //唤醒后,三个线程都具

JavaSE复习日记 : Java操作符\关系运算符\逻辑运算符\赋值运算符\字符串连接符\三元运算符

// Java操作符\关系运算符\逻辑运算符\赋值运算符\字符串连接符\三元运算符 /* * 一 Java操作符 * * Java操作符都有哪些? * +, -, *, /, %, ++, -- * 这里需要注意 a++ 和 ++a 的区别,后面说; */ /* public class Javase{ public static void main(String[] args){ int a = 10; int b = 20; int c = 30; System.out.println( a

JavaSE复习_12 Socket网络编程

△客户端使用Scanner与BufferedReader的异同,Scanner在客户端调用s.shutdownoutput的时候,将会因为读不到行而报异常,但是BufferedReader的readline方法则会正常终止.因此应当根据实际情况选择客户端服务端的流输入. △实例:根据DatagramSocket和DatagramPacket建立发送端和接收端. 接收端: public class Receive { public static void main(String[] args) t