java编程基础(3)

4.5 异常(Exception)
什么是异常
尽管人人希望自己身体健康,处理的事情都能顺利进行,但在实际生活中总会遇到各种状况,比如感冒发烧,工作时电脑蓝屏、死机等。同样,在程序运行的过程中,也会发生各种非正常状况,比如程序运行时磁盘空间不足、网络连接中断、被装载的类不存在等。针对这种情况,在Java语言中,引入了异常,以异常类的形式对这些非正常情况进行封装,通过异常处理机制对程序运行时发生的各种问题进行处理。
a5b36a83598e40ada554ac61e58a3146.png

 Throwable有两两个直接子类Error和Exception,其中Error代表程序中产生的错误,Exception代表程序中产生的异常。b95d91ce39894c4d9c0b3322ec173122.png

f4a78b3502f94a2c8c9857ecb8ad80d2.png 

 

Error类称为错误类,它表示Java运行时产生的系统内部错误或资源耗尽的错误,是比较严重的,仅靠修改程序本身是不能恢复执行的。举一个生活中的例子,在盖楼的过程中因偷工减料,导致大楼坍塌,这就相当于一个Error。使用java命令去运行一个不存在的类就会出现Error错误。

·Exception类称为异常类,它表示程序本身可以处理的错误,在开发Java程序中进行的异常处理,都是针对Exception类及其子类。在Exception类的众多子类中有一个特殊的RuntimeException类,该类及其子类用于表示运行时异常,除了此类,Exception类下所有其他的子类都用于表示编译时异常。

 try...catch和finally
Java中提供了一种对异常进行处理的方式--异常捕获。异常捕获通常使用

try….catch语句,具体语法格式如下:

tryl{

//程序代码块·

)catch(ExceptionType(Exception类及其子类)e){

1/对ExceptionType的处理)

其中在trv代码块中编写可能发生异常的Java语句,catch代码块中编写针对异常进行处理的代码。当try代码块中的程序发生了异常,系统会将这个异常的信息封装成一个异常对象,并将这个对象传递给catch代码块。catch代码块需要一个参数指明它所能够接收的异常类型,这个参数的类型必须是Exception类或其子类。

23efd36da3374054a257c91f5cd098ab.png

6fa3fef825804649b830673bcc5dc63e.png 

 

 throws关键字
在上一小节学习的文件4-35Example22iava中,由于调用的是自己写的divide()方法,因此很清楚该方法可能会发生异常。试想一下,如果去调用一个别人写的方法时,是否能知道别人写的方法是否会有异常呢?这是很难做出判断的。针对这种情况,Java中允许在方法的后面使用throws关键字对外声明该方法有可能发生的异常,这样调用者在调用方法时,就明确地知道该方法有异常,并且必须在程序中对异常进行处理,否则编译无法通过。

throws关键字声明抛出异常的语法格式如下:

修饰符 返回值类型方法名([参数1,参数2.....1)throwa ExceptionTypell,ExceptionType2.....l- 

从上述语法格式中可以看出,throws关键字需要写在方法声明的后面,throws后面需要声明方法中发生异常的类型,通常将这种做法称为方法声明抛出一个异常

 运行时异常和编译时异常
在实际开发中,经常会在程序编译时产生一些异常,而这些异常必须要进行处理,这种异常被称为编译时异常,也称为checked异常。另外还有一种异常是在程序运行时产生的,这种异常即使不编写异常处理代码,依然可以通过编译,因此被称为运行时异常,也称为unchecked异常。接下来就分别对这两种异常进行详细的讲解。

1. 编译时异常
>在Java中,Exception类中除了RuntimeException类及其子类都是编译时异常。编译时异常的特点是Java编译器会对其进行检查,如果出现异常就必须对异常进行处理,否则程序无法通过编译。处理编译时期的异常有两种方式:·

使用try….catch语句对异常进行捕获

使用throws关键字声明抛出异常,调用者对其处理。

2.行时异常
>RuntimeException类及其子类都是运行时异常。运行时异常的特点是Java编译器不会对其进行检查,也就是说,当程序中出现这类异常时,即使没有使用try..catch语句捕获或使用throws关键字声明抛出,程序也能编译通过。运行时异常一般是由程序中的逻辑错误引起的,在程序运行时无法恢复。比如通过数组的角标访问数组的元素时,如果超过了数组的最大角标,就会发生运行时异常,代码如下所示:

int[] arr=new int[5];

System.out.println(arr[6]);

上面代码中,由于数组arr的length为5,最大角标应为4,当使用arr[6]访问数组中的元素就会发生数组角标越界的异常。

自定义异常
JDK中定义了大量的异常类,虽然这些异常类可以描述编程时出现的大部分异常情况,但是在程序开发中有时可能需需要描述程序中特有的异常情况,例如文件4-38中在divide()方法中不允许被除数女为负数。为了解决这个问题,在Java中允许用户自定义异常,但自定义的异常常类必须继承自Exception或其子类。

 在Java中,针对类、成员方法和属性提供了四种访问级别,分别是private、 default、protected和public。

private> default> protected> public 

访问控制级别由小到大

上图中展示了Java中的四种访问控制级别,具体介绍如下:

·private(类访问级别):如果类的成员被private访问控制符来修饰,则这个成员只能

被该类的其他成员访问,其他类无法直接访问。类的良好封装就是通过private关键字来实现的。

·default(包访问级别):如果一个类或者类的成员不使用任何访问控制符修饰,则称它为默认访问控制级别,这个类或者类的成员只能被本包中的其他类访问。

protected(子类访问级别):如果一个类类的成员被protected访问控制符修饰,那么这个成员既能被同一包下的其他类访问, 也能被不同包下该类的子类访问。 

public(公共访问级别):这是一个最宽松的访问控制级别,如果一个类或者类的成员被public访问控制符修饰,那么这个类或者类的成员能被所有的类访问,不管访问类与被访问类是否在同一个包中。

接下来通过一个表将这四种访问级别更更加直观的表示出来,如下表所示。

c0cd39aa795d4efd83da1bebd80a51b2.jpg

 

异常

在Java中,异常是指在程序运行期间可能出现的错误或异常状况。这些异常可以由Java程序自行捕获和处理,从而可以帮助程序员开发更健壮和可靠的应用程序。

Java中的异常分为两类:

Checked Exception和Unchecked Exception。Checked

Exception是在编译期就可以检查出来的异常,需要明确地进行处理。 UncheckedException是在运行期间才会出现的异常,属于程序员的错误或代码问题。

以下是Java异常处理的关键字和语法:

try-catch语句:try-catch语句是Java异常处理的基本语法。try代码块内包含可能发生异常的代码,catch代码块用于捕获并处理异常。如果try代码块中的代码块执行成功,则不会执行catch代码块。

finally语句:finally代码块是Java中用于处理一些必须在代码块结束时执行的代码,不管try代码块是否出现异常都将执行。

throw语句:throw语句用于手动抛出一个异常。抛出异常后,程序会尝试查找匹配的catch块进行处理。

throws语句:在方法定义中使用throws语句,可以指定一种或多种异常类型,表示该方法可能抛出这些异常。

以下是一个Java异常处理示例:

public static void main(String[] args) {

 try {

int num1 = 10;

        int num2 = 0;

        int result = num1/num2;

        System.out.println("Result: " + result);

    } catch (ArithmeticException e) {

        System.out.println("Division by zero is not allowed.");

    } finally {

        System.out.println("Finally block is always executed.");

    }

}在本示例中,程序会尝试用num1除以num2,即10/0,这将产生一个ArithmeticException异常。由于调用了try-catch结构,程序将跳过try块,并跳转到catch块,输出一条错误消息。然后,程序执行finally块中的代码,并输出一条最终消息。 

而try语句有下列几个特点。

1.如果在try语句内的代码块产生了异常,那么将会被下面的catch语句进行捕获,会和catch语句进行异常类型匹配,如果匹配成功则,进入该catch语句,不在进行后面的catch语句匹配。这点与if else语句类似。

2.在异常产生并被捕获后,并在执行完catch语句后,程序不会停止,会继续往下执行。

3.如果在try语句内产生异常,但是在catch语句内没有与之匹配的异常类型,那么该异常会交给JVM进行默认处理。

4.在try内某行代码产生异常后,在try语句该行以下的程序不会被执行了,将会跳转catch语句进行异常匹配处理。

5.如果在try内的代码块,没有出现异常,那么依次将try内的语句执行完毕,不会执行catch语句。

一般的,在try、catch语句中,try语句中不会只产生一种异常,那么对异常类型的匹配catch语句就不会只有一条,那么如果在catch语句内的异常类型有父子关系,那么父类异常的catch语句必须放置在子类异常的catch语句下面。因为父类异常是可以接收子类异常的,可以形成多态的关系,那么拿子类异常进行匹配时,父类异常也是可以接收的。那么如果子类异常放置在父类异常下面,那么子类异常catch将永远不会被执行。

例如在以下代码中,Exception是父类异常,而NullPointerException等是Exception异常的子类,那么两个子类异常匹配将永远不会执行,所以编译器给出了警告。

204cd5a2751e4aa5b7096b2959aefacf.jpg

 

 权限修饰符

1.Java中一共有四种权限修饰符,它们分别是:

2.public:公共访问修饰符。使用public修饰的类、方法及成员变量可以被本包或其他包中的类访问。

3.protected:受保护访问修饰符。使用protected修饰的方法及成员变量可以被本包中的类和其他包中的子类访问。

4.default (即默认或不加修饰符):默认访问修饰符。使用默认修饰符的类、方法及成员变量只能被本包中的类访问。

5.private:私有访问修饰符。使用private修饰的类、方法及成员变量仅能被本类访问。

以下是一个Java类及其成员变量的权限示例:

public class Person {

    public String name;

    protected int age;

    String gender; // default

    private int id;

  public Person(String name, int age, String gender, int id) {

        this.name = name;

        this.age = age;

        this.gender = gender;

        this.id = id;

    }

}

在本示例中,Person类和其成员变量的访问权限如下:

name:public。可以被任意类访问。

age:protected。可以被Person类及其子类中访问,也可以被同一个包中的其他类访问。

gender:default。可以被同一个包中的其他类访问。

id:private。仅能被Person类中访问,其他类无法访问。

注意:权限修饰符不仅可以用于类中的属性或方法,同样也可以使用于类上。类的访问权限只能使用public和默认,不能使用protected和private。

StringBuilder类

 Java中的StringBuilder类用于动态地构建字符串。在之前的文章中,已经提到过了,在Sting类中它的存储数据的数组是被final修饰了的,所以说在Java中的String类是不可变的,也就是说,一旦创建了一个String对象,它的值就不能被更改。

而StringBuilder类提供的方法允许我们添加、删除和修改其字符串缓冲区中的内容。

它的底层实现也是使用char类型数组实现存储数据的,但是没有被final修饰,且空参构造初始化时默认给定16个char类型大小的空间,每次在添加数据时,会判断需要添加的目标字符产与本身数组的空间是否足够,足够的话直接添加进数组中,不足的话,会先进行扩容,然后再添加。

JDK7新特性

JDK 7(Java SE 7)在Java语言中引入了一些新特性,以下是其中的一些:

String在switch中可用:在Java SE 7之前,在switch语句中只允许使用数字和枚举类型的常量。但是,在Java SE 7中,我们可以使用字符串(String)作为开关变量。

自动资源管理:Java SE 7引入了try-with-resources语句,它是一种保证实现了必要释放资源的try语句的简化写法。在try代码块中初始化的资源(如文件流)将在try块退出时自动关闭。这种机制可以帮助程序员避免资源泄漏问题,使代码更加简洁。

数字字面量增强:在Java SE 7中,我们可以使用下划线来分隔数字字面量,使其更易读。例如,我们可以使用1_000_000表示一百万。

泛型实例化类型自动推断:在Java SE 7之前,当我们创建一个泛型实例时,必须明确地提供类型参数。但是现在,我们可以让编译器根据左侧的引用变量自动推断类型,从而使代码更加简洁。

异常多重捕获:在Java SE 7中,我们可以使用管道符(|)来捕获多个异常类型,这使得代码更加简洁。

Fork/Join框架:Java SE 7引入了Fork/Join框架,它是一种用于在多个处理器上并行执行任务的框架。它提供了一种简单的编程模型,可以让开发者更容易地实现并行算法和任务。

NIO 2.0:Java SE 7引入了NIO 2.0,它提供了更加强大和灵活的文件系统API。新的API支持异步IO和文件锁定等功能,提供了更高效和可伸缩的IO操作。

G1垃圾回收器:Java SE 7引入了G1垃圾回收器,它是一种可预测的垃圾回收器,可以在多处理器和大内存环境中提高性能。

增强的Java安全性:Java SE 7引入了许多新的安全性特性,如增强的XML处理器、增强的启动类加载器和支持加密协议的JSSE等。这些功能为Java应用程序提供了更高的安全性。
 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值