一、异常类
1.在Java中,异常分为三种类型
:Checked Exception(检查异常)、Unchecked Exception(非检查异常)和Error(错误)。
(1)检查异常(Checked Exception): 检查异常是指在编译阶段就需要捕获或声明的异常。它们是Exception类或其子类的子类,但不是RuntimeException类或其子类的子类。检查异常通常表示程序可能处理的可预知的错误或异常情况。在方法声明中必须显式声明检查异常,或者使用try-catch块捕获和处理异常,否则编译时会报错。
(2)非检查异常(Unchecked Exception): 非检查异常是指在编译阶段不需要捕获或声明的异常。它们是RuntimeException类或其子类的子类。非检查异常通常表示程序中出现的意外错误或异常情况,如空指针异常、数组越界异常等。编译器不会在编译时检查非检查异常,可以选择捕获和处理,但不强制要求。
(3)错误(Error): 错误是指程序无法处理的严重问题,通常是虚拟机内部错误或资源耗尽等不可恢复的错误。与异常不同,错误通常不应该被捕获和处理,而是由Java虚拟机自行处理。
2.例子:
(1)索引越界
(2)编辑错误
二、捕获 抛出 自定义异常类
1.捕获
我们可以通过捕获来处理异常。我们通常用try-catch-final来实现捕获。主要的结构是一下这样的:
try{
可能会出现异常的语句;
}
catch(相应的异常){
对应手段;
}
finally{
异常的出口;
}
2.抛出
因为不是所有的异常都报错在运行时,像是CloneNotCupportedException这个异常类是报错在编译期间的,所以我们要保证这个程序的运行,我们就得主动的抛出这个异常,使得程序正常运行。
我们通常用throw来直接抛出我们异常:
int a,b;
Scanner reader = new Scanner(System.in);
a=reader.nextInt();
b=reader.nextInt();
try {
if (b == 0) {
throw new ArithmeticException();
}
System.out.println(a / b);
} finally {
}
3.自定义异常类
对于特定的问题可以按照Java对问题封装的思想,将特有的问题自定义为异常类。
创建自定义异常类时注意:
(1)为自定义异常类取一个能标识异常状况的有意义的名字,能够根据名字判断异常类型。
(2)一般的,用户自定义异常大多为运行时异常,令其继承Exception或者RuntimeException类。
(3)自定义异常需要提供serialVersionUID。
(4)自定义的异常必须通过throw手动自行抛出,它抛出的不是异常类,而是异常对象,每次只能抛出一个对象。
(5)在异常类中至少定义两个构造方法,一个是无参构造方法,另一个是带String对象的参数的构造方法,将此对象传递给父类Exception的相同构造方法,这个对象将作为该异常对象的描述信息,即getMessage()方法的返回值。
例如,自定义一个异常类如下:
public class RegisterException extends Exception {
static final long serialVersionUID=34897193246939L;
public RegisterException(){}
public RegisterException(String s){
super(s);
}
}
测试类如下:
import java.util.*;
public class UserRegisteTest {
public void regist(int num) throws RegisterException{
if(num<0)
throw new RegisterException("注册账号为负值,不合理");
else
System.out.println("注册编号为:"+num);
}
public static void main(String[] args) {
UserRegisteTest t=new UserRegisteTest();
Scanner scn=new Scanner(System.in);
int ID=scn.nextInt();
try{
t.regist(ID);
} catch (RegisterException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
输出结果有以下可能:
①当输入的数大于或等于0时,如:
0
注册编号为:0
②当输入的数小于0时,如:
-1
注册账号为负值,不合理
RegisterException: 注册账号为负值,不合理
at UserRegisteTest.regist(UserRegisteTest.java:5)
at UserRegisteTest.main(UserRegisteTest.java:14)
上述代码中,regist()方法用throw抛出了自定义的异常,该方法本身不处理该异常,而是继续向上面一层抛出。main()方法调用regist(),编译器会强制要求main()方法处理RegisterException,并打印异常跟踪栈信息。
三、包装类 String BigDecimal
1.String
String是Java里面非常常见的一种包装类,其是我们所熟知的字符串类型,正如我们刚刚在上面提及到的包装性转换String类型。String还有像是直接拼接,和查询对应位置的字符,转换字符数组等功能。
StringBuffer支持对于一个单个字符进行修改,且可以和String类型互相转换,但是不像String类型声明,必须通过new来创建新的对象,毕竟同样是类。
2.BigDecimal
在进行浮点数 long 或 double 类型的运算时,如果直接进行运算,浮点数的运算会出现精度失准的情况,特别是在计算和金额相关的运算时,必须计算精确,不能出现误差,BigDecimal 的出现就是为了解决 浮点数类型的运算精度失准的场景;
通常情况下,我们会使用String对象作为参数来构造一个精确的BigDecimal对象。 下面提供的三种方法都是可以的:
//方法一
BigDecimal bg1 = new BigDecimal("1.1");
//方法二
BigDecimal bg2 = new BigDecimal(Double.toString(1.1));
//方法三
BigDecimal bg3 = BigDecimal.valueOf(1.1);
System.out.println(bg1.toString());
System.out.println(bg2.toString());
System.out.println(bg3.toString());
四、泛型 列表 set map
1.泛型
java 泛型(Generic)是 Java 5 中引入的一种特性,它允许类、接口和方法在定义时使用一个或多个类型参数,这些类型参数在调用时会被实际类型替换,从而增强了代码的重用性和类型安全性。通过使J用泛型,我们可以编写出更加通用的代码,同时也可以减少代码中的强制类型转换操作,提高代码的可读性和可维护性。
在 Java 泛型中,我们可以使用以下符号来定义泛型:
<T>:表示定义一个类型参数 T,可以是任何标识符,通常用大写字母表示,例如 List。
<E>:表示定义一个元素类型参数 E,通常用于集合类中,例如 List。
<K, V>:表示定义一个键值对类型参数 K 和 V,通常用于 Map 类中,例如 Map<K, V>。
在使用泛型时,可以将实际类型作为参数传递给泛型,例如 List,这样就可以创建一个只能存储 String 类型元素的列表。泛型在 Java 中的实现方式是使用类型擦除技术,即在编译时将泛型类型转换为原始类型,从而避免了类型检查的开销和运行时的类型转换。
2.列表
"List<String> list = new ArrayList<>();"声明了一个String类型的一个列表。我们可以通过add进行添加,remove进行删除,set进行修改
3.set 类似于c++的stl库中的集合
4.map 就是字典