异常:在Java语言中,将程序执行中发生的不正常情况称为“异常”。
(开发过程中的语法错误和逻辑错误不是异常)
Java程序在执行过程中所发生的异常事件可分为两类:
Error:Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源
耗尽等严重情况。比如:StackOverflowError和OOM。一般不编写针对性的代码进行处理。
Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,可以使
用针对性的代码进行处理。例如:
- 空指针访问
- 试图读取不存在的文件
- 网络连接中断
- 数组角标越界
运行时异常
是指编译器不要求强制处置的异常。一般是指编程时的逻辑错误,是程序 员应该积极避免其出现的异常。java.lang.RuntimeException类及它的子 类都是运行时异常。 对于这类异常,可以不作处理,因为这类异常很普遍,若全处理可能会对程序的可读性和运行效率产生影响。
编译时异常
是指编译器要求必须处置的异常。即程序在运行时由于外界因素造成的一 般性异常。编译器要求Java程序必须捕获或声明所有编译时异常。 对于这类异常,如果程序不处理,可能会带来意想不到的结果。
Java异常处理的方式:
方式一:try-catch-finally
方式二:throws + 异常类型
异常注意点
- 如果一个方法内抛出异常,该异常对象会被抛给调用者方法中处 理。如果异常没有在调用者方法中处理,它继续被抛给这个调用 方法的上层方法。这个过程将一直继续下去,直到异常被处理。 这一过程称为捕获(catch)异常。
- 如果一个异常回到main()方法,并且main()也不处理,则程序运行终止。
- 程序员通常只能处理Exception,而对Error无能为力。
try
捕获异常的第一步是用try{...}语句块选定捕获异常的范围,将可能出现异常的代码放在try语句块中。
catch (Exceptiontype e)
在catch语句块中是对异常对象进行处理的代码。每个try语句块可以伴随一个或多个catch语句,用于处理可能产生的不同类型的异常对象。如果明确知道产生的是何种异常,可以用该异常类作为catch的参数;也可以用其父类作为catch的参数。
比 如 : 可 以 用 ArithmeticException 类 作 为 参 数 的 地 方 , 就 可 以 用 RuntimeException类作为参数,或者用所有异常的父类Exception类作为参数。但不能是与ArithmeticException类无关的异常,如NullPointerException(catch中的语句将不会执行)。
finally
捕获异常的最后一步是通过finally语句为异常处理提供一个统一的出口,使得在控制流转到程序的其它部分以前,能够对程序的状态作统一的管理。不论在try代码块中是否发生了异常事件,catch语句是否执行catch语句是否有异常,catch语句中是否有return finally块中的语句都会被执行。
finally语句和catch语句是任选的
1. 请列举你所知道的各种异常(至少两种)?
在编程中,异常是一种特殊的对象,用于处理程序中出现的错误或异常情况。根据您所使用的编程语言和上下文,可以存在多种类型的异常。以下是一些常见的异常类型:
- 运行时异常:这是在程序运行过程中出现的异常,通常是由于编程错误导致的。例如,空指针异常(NullPointerException)在Java中是一种常见的运行时异常,当试图访问一个空对象的方法或属性时就会抛出。
- 编译时异常:这种异常在编译阶段就会被捕获,通常是由于程序中的逻辑错误或类型不匹配等原因导致的。例如,在Java中,数组越界异常(ArrayIndexOutOfBoundsException)是一种编译时异常,当尝试访问数组的非法索引时就会抛出。
- 自定义异常:开发者可以创建自己的异常类型,以更好地描述特定应用程序中的问题。例如,在Java中,可以通过继承
Exception类来创建自定义异常。 - IO异常:这是与输入/输出操作相关的异常,例如文件读取或写入错误。
2. 常见的异常类型有哪些?
- 运行时异常:这种异常通常在程序运行时出现,例如空指针异常、数组越界异常、类型转换异常等。这些异常通常是由于编程错误或逻辑错误导致的,例如尝试访问空对象的方法或属性,或尝试将一个对象强制转换为不兼容的类型。
- 编译时异常:这种异常在编译阶段就会被捕获,例如类未找到异常、输入/输出异常等。这些异常通常是由于程序中的逻辑错误或类型不匹配等原因导致的。
3. 如何自定义异常?
在Java中,自定义异常类需要继承自Exception类或其子类。以下是一个简单的自定义异常类的示例:
public class MyException extends Exception {
public MyException() {
super(); }
public MyException(String message) {
super(message);
}
public MyException(Throwable cause) {
super(cause);
}
public MyException(String message, Throwable cause)
{
super(message, cause); } }
这个自定义异常类继承自Exception类,并提供了几个构造函数,这些构造函数可以接受一个字符串和一个Throwable对象作为参数。这样,您就可以在需要自定义异常时使用这个类。例如:
public void doSomething() throws MyException { // ... 执行某些操作 ... if (someErrorCondition) { throw new MyException("An error occurred"); } // ... 继续执行其他操作 ... }
在上面的示例中,如果某个错误条件满足,就会抛出一个MyException异常。在调用这个方法的代码中,可以使用try-catch语句来捕获并处理这个异常:
try { doSomething(); } catch (MyException e) { e.printStackTrace(); // 打印异常堆栈跟踪信息到标准错误流(通常是控制台) }
4. 包装类的常用方法有哪些?
包装类是Java中用于包装基本数据类型的类,主要包括Integer、Double、Float等。这些包装类提供了许多有用的方法来处理基本数据类型。以下是一些常用的包装类方法:
- 转换方法:用于将基本数据类型转换为包装类对象或将包装类对象转换为基本数据类型。例如,
Integer.parseInt()可以将字符串转换为整数,而Integer.valueOf()可以将基本数据类型整数转换为Integer对象。 - 比较方法:用于比较两个包装类对象是否相等或比较包装类对象与基本数据类型值的大小关系。例如,
Integer.compare(int a, int b)可以比较两个整数的大小关系,而Integer.equals()可以比较两个Integer对象是否相等。 - 位操作方法:用于对包装类对象进行位运算。例如,
Integer.bitCount()可以计算一个整数的二进制表示中的位数,而Integer.rotateLeft()和Integer.rotateRight()可以对整数进行循环移位操作。 - 进制转换方法:用于将包装类对象从一种进制转换为另一种进制。例如,
Integer.toBinaryString()可以将整数转换为二进制字符串,而Integer.toHexString()可以将整数转换为十六进制字符串。 - 其他常用方法:还有其他一些常用的方法,如获取包装类对象的最大值、最小值、绝对值等。例如,
Integer.max(int a, int b)可以返回两个整数中的较大值,而Integer.abs()可以返回整数的绝对值。
这些方法提供了对基本数据类型的有用操作,使得使用包装类可以更加方便地处理基本数据类型。
5. int a=3,String b=“3”,请问a==b吗?
在Java中,int a=3 和 String b="3" 表示两个完全不同类型的变量:一个整数和一个字符串。== 操作符在Java中用于比较两个引用是否指向内存中的同一个对象。在这种情况下,a 和 b 显然指向不同的对象,所以 a == b 的结果会是 false。
这里要注意的是,尽管 b 的值是数字 3 的字符串表示,但字符串在Java中是不可变的,所以 b 和 "3" 指向的是不同的对象。即使字符串的内容相同,也不意味着两个不同的字符串对象是相同的。
如果你想比较两个字符串的内容是否相同,应该使用 equals() 方法,例如 b.equals("3"),这将返回 true
6. java中的异常处理关键字是什么?
在Java中,异常处理的关键字有以下几个:
try: 用于捕获可能会抛出异常的代码块。catch: 用于捕获并处理特定的异常。finally: 无论是否发生异常,都会执行此代码块。throw: 用于手动抛出一个异常。throws: 用于声明方法可能会抛出的异常。
这些关键字在Java的异常处理机制中起着至关重要的作用,帮助开发者更好地管理程序的运行状态和资源。
7. Java中throw和throws关键字有什么区别?
在Java中,throw和throws是两个用于异常处理的关键字,但它们在用途和上下文中有一些重要的区别。
-
throw:
throw关键字用于在代码中明确地抛出一个异常。这通常意味着你意识到某些条件或情况可能引发错误,并希望立即处理它。- 你可以使用
throw来抛出任何对象,包括自定义异常。 throw可以在方法中的任何位置被使用,但通常用于方法体内部。- 当使用
throw时,程序控制流立即中断,并转到相应的异常处理代码(如果有的话)。
-
throws:
throws关键字用于声明一个方法可能会抛出的异常。这告诉调用该方法的代码要准备处理这些异常。- 你只能使用
throws来声明一个或多个已定义的异常类型。 throws出现在方法签名中,以告诉调用者这个方法可能会抛出某些异常。- 在方法体内部,你可能不会使用
throw来直接抛出这些异常,而是在方法结束时使用return或continue等控制语句来表明方法正常结束或出现异常。
8. 集合和数组的区别?
- 数据元素类型:数组既可以存储基本数据类型,也可以存储引用数据类型。而集合只能存储引用数据类型(对象)。
- 长度:数组的长度是固定的,一旦初始化后,其长度不能改变。而集合的长度是可变的,可以根据元素的增加或减少而自动调整。
- 使用场景:数组多用于元素个数是固定的场景,因为一旦创建后,其大小无法改变。而集合多用于元素个数是不固定的场景,因为其大小可以动态调整。
- 效率:数组无论是效率还是检查类型都是最好的。因为数组是JAVA语言内置的数据类型,它是一个线性的序列,所以它可以快速地访问其他的元素。
- 底层实现:数组是连续的内存空间,其内存分配是连续的。而集合通常是由散列表等数据结构实现,其内存分配是不连续的。
9. IO流的分类
IO流主要分为输入流和输出流,输入和输出是以内存为基准的。数据进入内存被称为输入,数据写出内存被称为输出。
按处理数据单位不同可以分为字节流和字符流。字节流以字节为单位进行输入输出,如FileInputStream和FileOutputStream。字符流以字符为单位进行输入输出,如FileReader和FileWriter。
按处理方式的不同可以分为节点流和处理流。节点流直接与程序连接,处理流在已存在的流(字节流或处理流)之上,通过对数据的处理提供更为强大的读写功能,如BufferInputStream和BufferOutputStream。
此外,还可以根据流的方向分为输入流跟输出流,根据对手数据的处理方式分为节点流和处理流。