JAVA学习笔记(四)

标签: JAVA

一、生成Javadoc文档

我们先来看一下java的API文档中Arrays类的sort方法:
这里写图片描述
我们在Eclipse中这样写道:

/**
 * 该类是数组操作算法的工具类,提供了大量的静态方法用来操作数组
 * @author Author
 *
 */
public class ArrayUtil {

    private ArrayUtil(){

    }

    /**
     * 使用算法对数组进行升序排序
     * @param arr 要排序的数组
     */
    public static void sort(int[] arr){
        //具体方法实现省略...
    }

    /**
     * 使用二分搜索法来搜索指定的int型数组,以获得指定的值。
     * 必须在进行此调用之前对数组进行排序(通过 sort(int[]) 方法)。
     * @param   arr    要搜索的数组
     * @param   key    要搜索的值
     * @return  如果存在则返回对应的索引,如果不存在则返回-1
     */
    public static int BinarySearch(int[] arr,int key){
        return -1;
    }
}

当生成文档时是这样的:
这里写图片描述

再来看一个例子:

/**
 * 定义一个可走路的规范,包含一个可走路的行为,适用于爬行动物
 * 
 * 
 * @author Author
 * @since Android 8.0
 * @see 另请参见www.baidu.com
 */
public interface IWalkable {
    /**
     *  可走路的行为
     */
    void walk();
}

生成文档时是这样的:
这里写图片描述
这里写图片描述

怎样生成文档:选中你想生成的文档,选择导出,选择javadoc,再点击完成即可。
这里写图片描述

二、异常处理机制

没有异常处理机制的困惑

 所谓异常,不是指语法错误,语法错误是编译错误,这样是无法生成字节码。
 异常处理是衡量一门语言是否成熟的标准之一,主流的语言Java,C++,C#等都是支持异常处理机制的。
 异常处理机制可以让程序有更好的容错性,使我们的代码更健壮。
但是传统的C语言并没有异常处理机制,此时程序员只能通过方法的特定返回值来表示异常情况,并且使用if语句来判断是否产生了异常,那没有异常会带来什么呢?

没有异常机制的缺点:
1.使用方法的返回值来表示异常情况有限,无法穷举出所有的异常情况;
2.异常流程代码和正常流程代码混在一起,增大了程序的复杂性,降低了可读性;
3.随着系统的规模扩大,可维护性降低。

针对没有异常处理机制的缺点,我们有以下解决方案:
解决方案:
1.把不同类型的异常情况描述成不同类(异常类);
2.分离异常流程代码和正常流程代码;
3.灵活处理异常,如果当前方法处理不了,应该交给调用者处理。

出现异常之后,程序运行会中断,所以我们要处理异常:
1.该方法不处理,而是声明抛出,由该方法的调用者来处理(throws);
2.在方法中使用try-catch的语句块来处理异常

使用try-catch捕获单个异常:
语法:

try{
    //编写可能会出现异常的代码
}catch(异常类型 e){
    //处理异常的代码
    //记录日志,打印异常信息,继续抛出异常
}

注意: try和catch必须一起使用,不能单独使用。

如何获取异常信息:(Throwable类的方法)
1.String getMessage():获取异常类的,描述信息;
2.String toString():获取异常类的类型和异常描述信息;
3.void printStackTrace():打印异常的跟踪栈信息并输入到控制台;
(System.err.println(“XXX”))
在开发中常用printStackTrace()


使用try-catch捕获单个异常:

try{
    //编写可能会出现异常的代码
}catch(异常类型A e){
    //处理异常的代码
    //记录日志,打印异常信息,继续抛出异常
}catch(异常类型B e){
    //处理异常的代码
    //记录日志,打印异常信息,继续抛出异常
}

注意:
1.一个catch语句只能捕获一种类型的异常,如果要捕获多个类型的异常,必须使用多个catch语句;
2.代码在运行时,只能同时拥有一种类型的异常。


finally语句块

finally语句块表示最终都会执行的代码,无论是否有异常

什么时候必须要用finally语句块:
 当我们在try语句块中打开了一些物理资源(磁盘文件 /网络连接/数据库连接等),我们都得在使用完之后,关闭这些资源。

finally的两种语法:

1.try…finally:此时我们没有用catch来捕获异常,因为此时根据具体情况,我们会抛出异常,自己不处理;
2.try…catch…finally:自身需要处理异常,最后还需要关闭资源。

注意: finally不能单独使用。

当只有在try或者catch中调用退出JVM的方法时,finally语句才不会执行,否则finally将永远执行。

关于finally的有趣的问题:
问下面代码输出结果为?

try {
        return 
                1;
    } finally {
        return 
                100;
    }

实际上输出100,因为先执行finally语句块。

那么下面的代码输出结果是多少:

int a = 1;
try {       
        return 
                a;
    } finally {
        ++
        a;
    }
System.out.println(a);

实际上输出1,因为try语句块中的a在程序进入时就确定了(具体的用断点调试一下,仍然是finally先执行)

抛出异常

throw语句:

用于方法内部,抛出一个异常对象:

throw new 异常类(异常信息);终止方法

一般的,当一个方法出现不正常的情况的时候,我们不知道该方法应该返回什么,此时就返回一个错误,在catch语句块中继续向上抛出异常。
return是返回一个值,throw是返回一个错误,返回给该方法的调用者。
如以下代码:

public static void main(String[] args) {
        try{
            int ret = divide(10,0);
            System.out.println(ret);
        } catch(ArithmeticException e) {
            System.out.println(e.getMessage());
        }
    }

    private static int divide(int num1, int num2) {
        System.out.println("begin...");
        if (num2 == 0) {
            throw new ArithmeticException("除数不能为0!!!");
        }
        System.out.println("--------------------");
        try {
            int ret = num1 / num2;
            System.out.println("结果为" + ret);
        } catch (ArithmeticException e) {
            e.printStackTrace();
        }
        System.out.println("end...");
        return 0;
    }

throws语句:

运用于方法声明之上,表明当前方法不处理异常,二十提醒该方法的调用者来处理异常(抛出异常)。
如果每一个方法都放弃处理异常,都直接通过throws声明抛出,最后异常会抛到main方法,如果此时main方法不处理,继续抛出给JVM,底层的处理机制就是打印异常的跟踪栈信息。(runtime异常就是默认这种处理方式)
如以下代码:

public static void main(String[] args) {
        try {
            int ret = divide(10, 0);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    private static int divide(int num1, int num2) throws Exception {
        System.out.println("begin...");
        if (num2 == 0) {
            throw new Exception("除数不能为0!!!");
        }
        System.out.println("------");
        try {
            int ret = num1 / num2;
            System.out.println("结果为" + ret);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("end...");
        return 0;
    }

自定义异常类

为什么需要自定义异常类?
Java中的不同异常类,分别别表示某一种特殊的异常情况,在开发中总是有些异常情况是Sun公司没有定义的。此时我们根据自己的业务的异常情况来定义异常类
什么是自定义异常类?
在开发中根据自己业务的情况来定义异常类。
异常类如何定义?
1.自定义一个受检查的异常类,并继承于Exception;
2.自定义一个运行时期的异常类,并继承于RuntimeException。

用以下代码作为Example:

//业务逻辑异常
public class LogicException extends RuntimeException{
    private static final long serialVersionUID = 1L;

    public LogicException() {
        super();
    }

    public LogicException(String message) {
        super(message);
    }

    /**
     * 
     * @param message 表示当前异常的原因/信息
     * @param cause   当前异常的根本原因
     */
    public LogicException(String message, Throwable cause) {
        super(message, cause);
    }
}

下面是模拟注册账户的自定义异常类:

public class RegisterDemo {
    //模拟数据库中已经存在的账号
    private static String[] names = {"will","lucy","Sue","Bob"};

    public static void main(String[] args) {
        try{
            //可能出现异常的代码
            checkUsername("will");
            System.out.println("注册成功!");
        }catch(LogicException e) {
            //处理异常
            String errorMes = e.getMessage();
            System.out.println(errorMes);
        }   
    }
    //判断当前账号是否存在
    public static boolean checkUsername(String username){
        for (String name : names){
            if (name.equals(username)){
                throw new LogicException("该用户名已经被注册");
            }
        }
        return true;
    }
}

Java7 的异常新特性

Android 用不到Java7,支持Java5和Java6的语法。
1.增强的throw:
Java7中处理抛出异常更精确了,不再笼统的使用Exception声明抛出。
2.多异常捕获:

try {
    //...
} catch (ArithmeticException | NumberFormatException e) {
    e.printStackTrace();
} catch (Exception e) {
    e.printStackTrace();
}

3.自动资源关闭:
Java7之前的关闭资源:

private static void test1() {
    OutputStream out = null;
    try {
        out = new FileOutputStream("F:/123.txt");
        out.write(1);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (out != null) {
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Java7中关闭资源:

private static void test2() {
    try (
            // 打开资源
            OutputStream out = new FileOutputStream("F:/123.txt");) {
        // 可能出现异常的代码
        out.write(1);
    } catch (Exception e) {
        // 处理异常
        e.printStackTrace();
    }
}

注意:try语句块()中的对象必须实现AutoCloseable的接口。

处理异常的原则

1.异常只能处理非正常情况,try-catch会影响性能;
2.需要为异常提供说明文档,比如Java doc,如果自定义了一个异常或某一方法抛出了异常,我们应该记录在文档注释中;
3.尽可能避免异常;
4.异常的粒度很重要,应该为一个基本操作定义一个try-catch块,不要为了简便将几百行代码放到一个try-catch块中;
5.不建议在循环中进行异常处理,应该在循环外对异常进行捕获处理;
6.自定义异常类尽量使用RuntimeException类型的。

几个常见的RuntimeException:
ArithmeticException(算术异常)
NullPointerException(空指针异常)
IndexOutOfBoundsException(索引越界)
ArrayIndexOutOfBoundsException(数组索引越界)
ClassCastException(类型强制转化异常)
NumberFormatException(数字格式化异常)


版权声明:本文为qq_42650988原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42650988/article/details/81669052

智能推荐

FFMPEG完美入门资料---002---FFmpeg 支持能力说明

接着上文写: 2.3.1 FFmpeg 对编码解码器的支持 ffmpeg 支持的编解码器种类共有 280 多种, 涵盖了几乎所有常见音视频编码格式, 能解码几乎所有的音视频, 每种音视频编解码器的实现都在 libavcodec 目录下有具体的 C 语言实现。 * 注:编码器和解码器的名称不是完全匹配的,因此有些编码器没有对应相同名称的解码器,反之, 解码器也一样。即使编码和解码都支持也不一定是完全...

20145107 《Java程序设计》第五次实验报告

实验简述: 在本周,我们进行了Java的第五次试验,本次实验的主要内容是结对编程。本次实验的大体过程是: 1.先进行Java的客户端与服务端的代码编写。结对是两个人,一人负责客户端,一人负责服务端。 2.利用加解密代码包,编译运行代码,客户端加密,服务器解密。 3.客户端加密明文后将密文通过TCP发送。 4.在本次的代码编写上,要求代码可以实现两者之间的数据传输,在代码传输的基础上加上一定的加密过...

更改springboot启动拼成的字母

1.更改springboot启动拼成的字母 其实很好改,只需要在resources下新建一个txt文件就可以,命名为banner.txt,那这种字符该怎么拼出来呢,下面推荐一个网址,有这种工具 传送门 2.集成...

Node.js安装配置

好久都没更新博客了,今天心血来潮,决定是时候更新一篇了,首先我们来认识一下node.js。 什么是node.js? 简单的说 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的...

RocketMQ之双Master集群搭建笔记记录

一:RocketMQ双master集群部署 服务器环境(我采用的虚拟机,centos6 .5【特别注意:安装的虚拟机centos系统一定得是64位的,32位的会启动不起来。即便起来了也会有很多问题,深坑勿踩】)  ip       用户名    密码        角色     模式 192.168.197.101   root        nameServer1,brokerServer1  ...

猜你喜欢

蓝桥杯试题集-基础练习题-数列特征(Java)

//做题笔记,仅自己看得懂 题目: 正确姿势:...

多线程爬取4k超高清美图壁纸

多线程爬取4k美图壁纸 前言:看完此篇文章你可以更加深入的了解多线程的使用,并且最重要的你能够下载你自己想要的超高清4k壁纸 爬取结果: 1. 分析网站 要爬取的url :http://pic.netbian.com/ a) 判断网页是动态加载还是静态加载页面。右击查看网页源代码,按Ctrl + f在源代码中搜索网站的详情页地址,从而判断整个网页是静态加载的 b) 明确爬取的目标。我们要爬取的目标...

elementUI-添加自定义图标

elementui的小图标有限,跟UI给的不一样,这个时候咋办呢?百度走起。。。。参考了两篇博主分享的 自定义elementui中的图标 和 建立图标库,这里主要用到第一种 实际中: elementUI导航栏 具体代码: 汉字转换Unicode编码: 直接打开控制台: 汉字.chatCodeAt().toString(16); 然后回车; 至于三角形的图标,我直接把箭头的 unicode 值改成了...

[Linux]——文件缓冲区

文件缓冲区 提到文件缓冲区这个概念我们好像并不陌生,但是我们对于这个概念好像又是模糊的存在脑海中,之间我们在介绍c语言文件操作已经简单的提过这个概念,今天我们不妨深入理解什么是文件缓冲区。 为什么需要文件缓冲区 当我们在程序中写下一条printf语句时,我们希望将这条语句的内容打印到屏幕上。但是如果你将语句放在循环中,难道你执行一次循环那么操作系统就要打印一次这条数据么?答案当然不是 我们对于程序...

基于FPGA的IIC协议详解——EEPROM控制器(1)

IIC协议举例 常用IIC协议使用地方 常见IIC协议的注意点 24LC64芯片读写命令的时序图 eeprom控制器的系统框图 时序图设计 代码设计 EEPROM控制器测试模块的代码 结束语 常用IIC协议使用地方 熟悉一个协议一定要知道这个协议应该用到什么地方,IIC协议作为飞利浦公司定义的一个慢速传输协议,常用于: 1、芯片寄存器的配置; 2、eeprom的读写; 本次实验我们将使用eepro...