练习-第09章_异常处理.md
少壮不努力,老大徒伤悲!
第09章_异常处理拓展练习
代码阅读题
1、阅读代码,分析结果
public static void main(String[] args) {
int test = test(3,5);
System.out.println(test);
}
public static int test(int x, int y){
int result = x;
try{
if(x<0 || y<0){
return 0;
}
result = x + y;
return result;
}finally{
result = x - y;
}
}
/*
* (1)finally块中的代码是无论try中是否发生异常,也无论catch是否可以捕获异常,
* 也不管try和catch中是否有return语句,都会执行的部分
* (2)如果finally中有return语句,那么try...catch...finally结构
* 一定从finally中的return回去
* (3)如果finally中没有return语句,那么try...catch...finally结构
* 才会从try或catch中的return回去,但是finally值中代码不会影响最终的返回值
*/
2、阅读代码,分析结果
public class Exercise2 {
public static void main(String[] args) {
try{
return;
}finally{
System.out.println("finally");
}
}
}
/*
* finally块中的代码是无论try中是否发生异常,也无论catch是否可以捕获异常,
* 也不管try和catch中是否有return语句,都会执行的部分
*/
3、阅读代码,分析结果
public class Exercise3 {
{
System.out.println("a");
}
static{
System.out.println("b");
}
Test03(){
System.out.println("c");
}
public static String getOut(){
try{
return "1";
}catch(Exception e){
return "2";
}finally{
return "3";
}
}
public static void main(String[] args) {
System.out.println(getOut());
}
}
/*
* (1)main()执行之前,需要先完成所在类的初始化
* (2)类初始化由两部分代码组成:①静态变量的显式赋值代码②静态代码块
* (3)没有创建对象,不会执行实例初始化相关的代码
* (4)finally块中的代码是无论try中是否发生异常,也无论catch是否可以捕获异常,
* 也不管try和catch中是否有return语句,都会执行的部分
* (5)如果finally中有return语句,那么try...catch...finally结构
* 一定从finally中的return回去
*/
4、阅读代码,分析结果
public class Exercise4 {
static int i = 0;
public static void main(String[] args) {
System.out.println(test());
}
public static int test(){
try{
return ++i;
}finally{
return ++i;
}
}
}
/*
* (1)finally块中的代码是无论try中是否发生异常,也无论catch是否可以捕获异常,
* 也不管try和catch中是否有return语句,都会执行的部分
* (2)如果finally中有return语句,那么try...catch...finally结构
* 一定从finally中的return回去,但是try和catch中的return语句中返回值的表达式会执行。
* (3)如果finally中没有return语句,那么try...catch...finally结构
* 才会从try或catch中的return回去,但是finally值中代码不会影响最终的返回值
*/
5、阅读代码,分析结果
public class Exercise5 {
public static void main(String[] args) {
int a = -1;
try{
if(a>0){
throw new RuntimeException("");
}else if(a<0){
throw new IOException("");
}else{
return ;
}
}catch(IOException ioe){
System.out.println("IOException");
}catch(Throwable e){
System.out.println("Throwable");
}finally{
System.out.println("finally");
}
}
}
/*
* (1)throw用于手动抛出异常
* (2)无论是JVM抛出的异常还是throw抛出的异常都需要catch处理
* (3)catch是多分支结构,从上到下按顺序匹配,只会进入第一个匹配上的catch分支
* (4)finally块中的代码是无论try中是否发生异常,也无论catch是否可以捕获异常,
* 也不管try和catch中是否有return语句,都会执行的部分
*/
6、阅读代码,分析结果
public class Exercise6 {
public static int fun(){
int result = 5;
try{
result = result / 0;
return result;
}catch(Exception e){
System.out.println("Exception");
result = -1;
return result;
}finally{
result = 10;
System.out.println("I am in finally.");
}
}
public static void main(String[] args) {
int x = fun();
System.out.println(x);
}
}
/*
* (1)finally块中的代码是无论try中是否发生异常,也无论catch是否可以捕获异常,
* 也不管try和catch中是否有return语句,都会执行的部分
* (2)如果finally中有return语句,那么try...catch...finally结构
* 一定从finally中的return回去
* (3)如果finally中没有return语句,那么try...catch...finally结构
* 才会从try或catch中的return回去,但是finally值中代码不会影响最终的返回值
*/
7、阅读代码,分析结果
public class Exercise7 {
public static int aMethod(int i)throws Exception{
try{
return i / 10;
}catch(Exception ex){
throw new Exception("exception in aMethod");
}finally{
System.out.println("finally");
}
}
public static void main(String[] args) {
try {
aMethod(0);
} catch (Exception e) {
System.out.println("exception in main");
}
}
}
/*
* (1)finally块中的代码是无论try中是否发生异常,也无论catch是否可以捕获异常,
* 也不管try和catch中是否有return语句,都会执行的部分
* (2)throw用于手动抛出异常
* (3)throws用于将异常抛给调用者处理
*/
8、笔试题:补充代码
给出下面的不完整的方法:
1
2 { int success = connnect();
3 if(success == -1){
4 throw new TimedOutException();
5 }
6 }
TimedOutException 不是一个 RuntimeException,继承于Exception。下面的哪些声明可以被加入第1行完成此方法的声明?( B、C)
A. public void method()
B. public void method() throws Exception
C. public void method() throws TimedOutException
D. public void method() throw TimedOutException
E. public throw TimedOutException void method()
简答题
9、请描述异常的继承体系
Java把所有的非正常情况分成两种:异常(Exception)和错误(Error),它们都继承Throwable父类。
10、请描述你对错误(Error)的理解
Error错误,一般是指与虚拟机相关的问题,如系统崩溃、虚拟机错误、动态链接失败等,这种错误无法恢复或不可能捕获,将导致应用程序中断。通常应用程序无法处理这些错误,因此应用程序不应该试图使用catch块来捕获Error对象。在定义该方法时,也无须在其throws子句中声明该方法可能抛出Error及其任何子类
11、请描述你对异常(Exception)的理解
Exception分为两大类:
运行时异常 [即程序运行时,发生的异常]。
编译时异常 [即编程时编译器检查出的异常,Checked异常]。
所有的RuntimeException类及其子类的实例被称为Runtime异常;不是RuntimeException类及其子类的异常实例则被称为Checked异常。
12、请描述你对运行时异常(RuntimeException)的理解
RuntimeException即程序运行时发生的异常,编译时检测不到这种异常,程序运行后,抛出异常
Runtime异常则更加灵活,Runtime异常无须显式声明抛出,如果程序需要捕获Runtime异常,也可以使用try…catch块来实现
13、throw与throws的区别
区别一:throw 是语句抛出一个异常;throws 是方法抛出一个异常;
区别二:throws可以单独使用,但throw不能;
区别三:throw要么和try-catch-finally语句配套使用,要么与throws配套使用。但throws可以单独使用,然后再由处理异常的方法捕获
14、异常处理方式有几种,分别是什么?详细阐述每种方式对异常是如何处理的
在java中,有一组关键字被用来进行异常的捕捉,它就是try-catch-finally。代码如下所示:
try{
// 尝试执行的可能会抛出异常的代码
}catch(异常类型1 异常的变量名1){
// 当异常抛出时,根据异常的类型和变量名执行对应的catch语句
//catch语句用来捕获异常。
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 不管最终如何,一定要执行的语句,一般做清理类型等收尾善后性质的工作
//finally不是必要出现的
}
此外,还有一组关键字被用来抛出异常,它就是throws/throw关键字:
如果一个方法没有捕获一个可查异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。
也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
下面方法的声明抛出一个 RemoteException 异常:
import java.io.*;
public class className{
public void deposit(double amount) throws RemoteException{
// Method implementation
throw new RemoteException();
}
//Remainder of class definition
}
一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
例如,下面的方法声明抛出 RemoteException 和 InsufficientFundsException:
import java.io.*;
public class className{
public void withdraw(double amount) throws RemoteException,InsufficientFundsException{
// Method implementation
}
//Remainder of class definition
}
15、请列举常见异常,并说明产生原因。
(1)java.lang.NullPointerException——空指针异常,
出现原因:调用了未经初始化或者不存在的对象。
(2)java.lang.ClassNoFoundException—— 指定类找不到,
出现原因:类的名称和路径加载错误,通常是试图通过字符串来加载某个类时可能引发异常。
(3)java.lang.NumberFormatException——字符串转换为数字异常,
出现原因:字符串数据中包含非数字型字符。
(4)java.lang.IndexOutOfBoundsException——数组下标越界异常,
出现原因:调用的下标超出了数组的范围。
(5)java.lang.IllegalArgumentException—— 方法传递参数错误,
出现原因:在很多j2me的类库中的方法,在一些情况下会引发这样的错误,比如本该是正数的被写成了负数。
(6)java.lang.ClassCastException——数据类型转换异常,
出现原因:强制类型转换类型不匹配时出现此异常。
(7)java.lang.illegalaccessexception——没有访问权限,
出现原因:当程序要调用一个类时,但是当前的方法没有对该类的访问权限。
(8)java.lang.SQLException——SQL异常,
出现原因:在执行sql语句时出现的各种异常。
(9)java.lang.InstantiationException——实例化异常,
出现原因:指不能实例化对象而出现的异常。
(10)java.lang.NoSuchMethodExceptioin—— 方法不存在异常,
出现原因:这个异常出现的原因有两个,第一,缺少某些jar文件;第二,某些jar文件有重复。
(11)java.lang.arithmeticexception——数学运算异常,
出现原因:出现不符合定义的运算,例如除以零。
编程题
16、新年倒计时
(1)已知java.lang包下有一个Thread类,这个类有一个静态方法:
public static void sleep(long millis) throws InterruptedException
调用这个方法可以实现程序休眠millis毫秒(1000毫秒=1秒)。
(2)在测试类的main中,在for循环中调用上面的sleep方法,实现新年倒计时10,9,8,…,1,新年到!
- 每循环1次执行一次sleep方法,可以模拟1秒输出一个数字。
- 使用try…catch处理异常
public class Exercise16 {
public static void main(String[] args) {
for (int i = 10; i >=1 ; i--) {
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("新年到!");
}
}
17、演示OOM错误
public class Exercise17 {
public static void main(String[] args) {
int[] arr = new int[Integer.MAX_VALUE];
}
}
/*
设置JVM参数
-verbose:gc
-Xms20M
-Xmx20M
-Xmn10M
-XX:+PrintGCDetails
-XX:SurvivorRatio=8
其中:
Xms:最小堆
Xmx:最大堆
Xmn:新生代的大小
PrintGCDetails:打印GC日志
SurvivorRatio:Eden区和Survivor比例
*/
public class Exercise17 {
public static void main(String[] args) {
ArrayList list=new ArrayList();
//通过不断的创建对象达到OOM
while (true){
list.add(new Object());
}
}
}
18、克隆对象
(1)声明一个Rectangle矩形类,
- 属性:length和width
- 无参和有参构造
- 提供get/set方法
- 重写toString方法,返回矩形对象信息
- 实现java.lang.Cloneable接口,重写Object类的clone()方法
(2)在测试类中,创建一个Rectangle矩形对象,调用矩形对象的clone方法克隆出一个新对象,
- 使用try…catch处理CloneNotSupportedException异常,在catch中手动创建一个矩形对象,并用原来的矩形对象的length和width为新创建的矩形对象的length和width赋值
public class Rectangle implements Cloneable{
private double length;
private double width;
public Rectangle() {
}
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public double getWidth() {
return width;
}
public void setWidth(double width) {
this.width = width;
}
@Override
public String toString() {
return "Rectangle{" +
"length=" + length +
", width=" + width +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Exercise18 {
public static void main(String[] args) {
Rectangle r1 = new Rectangle(4,2);
System.out.println("r1 = " + r1);
Rectangle r2;
try {
r2= (Rectangle) r1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
r2 = new Rectangle();
r2.setLength(r1.getLength());
r2.setWidth(r1.getLength());
}
System.out.println("r2 = " + r2);
}
}
19、输入两个整数相除
从键盘输入两个整数,求它们的商。尽量考虑和避免异常,无法避免的使用try…catch处理。
(1)如果用户输入的非整数,使用try…catch处理,并且让用户重新输入
(2)如果用户输入的除数为0,请用户重新输入。
public class Exercise19 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int a ;
while(true) {
try {
System.out.print("请输入被除数:");
a = input.nextInt();
break;
} catch (Exception e) {
input.nextLine();
System.out.println("输入错误,请重新输入!");
}
}
int b ;
while(true) {
try {
System.out.print("请输入除数:");
b = input.nextInt();
if(b==0){
System.out.println("除数不能为0,请重新输入");
}else {
break;
}
} catch (Exception e) {
input.nextLine();
System.out.println("输入错误,请重新输入!");
}
}
System.out.println(a + "/" + b + "=" + a/b);
input.close();
}
}
20、数组工具类
(1)声明数组工具类ArrayTools(自己写)
- 声明public static int max(int[] arr)返回数组的最大值。
- 声明public static boolean fromSmallToLarge(int[] arr)判断数组元素是否从小到大排序,如果是返回true,否则返回false。
- 声明public static int binarySearch(int[] arr ,int value)使用二分查找法返回value元素在arr的下标,如果有多个,返回第一次找到它的下标,如果不存在返回-1。另外,如果arr数组不是按照升序排列的数组抛出new RuntimeException(“数组元素不是从小到大”)异常对象。
- 以上三个方法都要对arr数组进行检查,如果arr为null抛出new NullPointerException(“数组不能为null”)异常对象,如果arr.length为0抛出new ArrayIndexOutOfBoundsException(“数组不能没有元素”)
- 声明public static String toString(int[] arr)返回数组的元素,如果arr为null,返回”“,如果arr.length为0,返回”[]”,否则返回元素,例如:“[1,2,3,4,5]”。
(2)运行如下测试类代码,对不同的arr分别测试(不用写,直接用)
public class Exercise20 {
public static void main(String[] args) {
// int[] arr = null;
// int[] arr = {}
// int[] arr = {3,2,1,4};
int[] arr = {1,5,16,28,39};
try {
System.out.println(ArrayTools.toString(arr));
System.out.println("最大值:" + ArrayTools.max(arr));
System.out.println("查找5:" + ArrayTools.binarySearch(arr,5));
} catch (Exception e) {
e.printStackTrace();
}
}
}
ArrayTools工具类代码:
public class ArrayTools {
private static void checkArr(int[] arr){
if(arr == null){
throw new NullPointerException("数组不能为null");
}
if(arr.length == 0){
throw new ArrayIndexOutOfBoundsException("数组不能没有元素");
}
}
public static int max(int[] arr){
checkArr(arr);
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if(arr[i] > max){
max = arr[i];
}
}
return max;
}
public static boolean fromSmallToLarge(int[] arr){
checkArr(arr);
for (int i = 0; i < arr.length - 1; i++) {
if(arr[i] > arr[i+1]){
return false;
}
}
return true;
}
public static int binarySearch(int[] arr ,int value){
checkArr(arr);
if(!fromSmallToLarge(arr)){
throw new RuntimeException("数组元素不是从小到大");
}
for(int left = 0,right = arr.length-1; left<=right; ){
int mid = left + (right-left)/2;
if(arr[mid] == value){
return mid;
}else if(value > arr[mid]){
left = mid + 1;
}else{
right = mid - 1;
}
}
return -1;
}
public static String toString(int[] arr){
if(arr == null){
return "";
}
String str = "[";
for (int i = 0; i < arr.length; i++) {
if(i==0){
str += arr[i];
}else{
str += "," + arr[i];
}
}
str += "]";
return str;
}
}
21、图形工具类,矩形工具类
(1)自定义InvalidValueException异常,继承Exception
(2)声明图形工具类GraphicTools
声明public static void printRectangle(int line, int column, char sign)输出line行column列由sign接收的字符组成的矩形,如果line或column<=0则抛出new InvalidValueException(“矩形的长和宽必须是正整数”)异常对象,如果sign字符编码不在[33,126]范围,则抛出new InvalidValueException(“组成矩形的必字符必须是数字字母和基本标点符号”)异常对象。
(3)在测试类中测试调用
public class InvalidValueException extends Exception{
public InvalidValueException() {
}
public InvalidValueException(String message) {
super(message);
}
}
public class GraphicTools {
public static void printRectangle(int line, int column, char sign) throws InvalidValueException {
if(line <=0 || column<=0){
throw new InvalidValueException("矩形的长和宽必须是正整数");
}
if(sign<33 || sign>126){
throw new InvalidValueException("组成矩形的必字符必须是数字字母和基本标点符号");
}
for (int i = 1; i <= line; i++) {
for (int j = 1; j <= column; j++) {
System.out.print(sign);
}
System.out.println();
}
}
}
public class Exercise21 {
public static void main(String[] args) {
try {
GraphicTools.printRectangle(5,5,'*');
} catch (InvalidValueException e) {
e.printStackTrace();
}
}
}
22、游戏角色
案例:
-
在一款角色扮演游戏中,每一个人都会有名字和生命值,角色的生命值不能为负数。
-
要求:当一个人物的生命值为负数的时候需要抛出自定的异常
操作步骤描述:
(1)自定义异常类NoLifeValueException继承RuntimeException
① 提供空参和有参构造
② 在有参构造中,需要调用父类的有参构造,把异常信息传入
(2)定义Person类
① 属性:名称(name)和生命值(lifeValue)
② 提供空参构造
③ 提供有参构造:使用setXxx方法给name和lifeValue赋值
④ 提供setter和getter方法:
在setLifeValue(int lifeValue)方法中,首先判断,如果 lifeValue为负数,就抛出NoLifeValueException,异常信息为:生命值不能为负数:xx;然后在给成员lifeValue赋值。
(3)定义测试类Test08
① 使用满参构造方法创建Person对象,生命值传入一个负数。由于一旦遇到异常,后面的代码的将不在执行, 所以需要注释掉上面的代码
② 使用空参构造创建Person对象
调用setLifeValue(int lifeValue)方法,传入一个正数,运行程序
调用setLifeValue(int lifeValue)方法,传入一个负数,运行程序
③ 分别对①和②处理异常和不处理异常进行运行看效果
public class NoLifeValueException extends RuntimeException{
public NoLifeValueException() {
super();
}
public NoLifeValueException(String message) {
super(message);
}
}
public class Person {
private String name;
private int lifeValue;
public Person() {
super();
}
public Person(String name, int lifeValue) {
super();
setName(name);
setLifeValue(lifeValue);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLifeValue() {
return lifeValue;
}
public void setLifeValue(int lifeValue) {
if(lifeValue<0){
throw new NoLifeValueException("生命值不能为负数:" + lifeValue);
}
this.lifeValue = lifeValue;
}
}
public class Exercise22 {
public static void main(String[] args) {
try {
Person p = new Person("白蛇",-1);
} catch (Exception e) {
e.printStackTrace();
}
try {
Person p2 = new Person();
p2.setLifeValue(10);
p2.setLifeValue(-10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
23、银行账户类
1、声明银行账户类Account
(1)包含账号、余额属性,要求属性私有化,提供无参和有参构造,get/set方法(其中balance没有set方法)
(2)包含public void withdraw(double money)取款方法,当取款金额为负数时,抛出Exception,异常信息为“越取你余额越多,想得美”,当取款金额超过余额时,抛出Exception,异常信息为“取款金额不足,不支持当前取款操作”
(3)包含public void save(double money)存款方法,当取款金额为负数时,抛出Exception,异常信息为“越存余额越少,你愿意吗?”
2、编写测试类,创建账号对象,并调用取款和存款方法,并传入非法参数,测试发生对应的异常。
public class Account {
private String id;
private double balance;
public Account() {
}
public Account(String id, double balance) {
this.id = id;
this.balance = balance;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getBalance() {
return balance;
}
public void withdraw(double money) throws Exception {
if(money<0){
throw new Exception("越取你余额越多,想得美");
}
if(money>balance){
throw new Exception("取款金额不足,不支持当前取款操作");
}
balance -= money;
}
public void save(double money) throws Exception {
if(money<0){
throw new Exception("越存余额越少,你愿意吗?");
}
balance += money;
}
}
public class Exercise23 {
public static void main(String[] args) {
Account a = new Account("111111",5000);
try {
a.withdraw(-5000);
} catch (Exception e) {
// e.printStackTrace();
System.err.println("取款失败," + e.getMessage());
}finally {
System.out.println("尝试取款-5000后," + a.getBalance() );
}
try{
a.withdraw(1000);
}catch (Exception e) {
// e.printStackTrace();
System.err.println("取款失败," + e.getMessage());
}finally {
System.out.println("尝试取款1000后," + a.getBalance() );
}
try{
a.withdraw(5000);
}catch (Exception e) {
// e.printStackTrace();
System.err.println("取款失败," + e.getMessage());
}finally {
System.out.println("尝试取款5000后," + a.getBalance() );
}
try{
a.save(-5000);
}catch (Exception e) {
// e.printStackTrace();
System.err.println("存款失败," + e.getMessage());
}finally {
System.out.println("尝试存款-5000后," + a.getBalance() );
}
try{
a.save(5000);
}catch (Exception e) {
// e.printStackTrace();
System.err.println("存款失败," + e.getMessage());
}finally {
System.out.println("尝试存款5000后," + a.getBalance() );
}
}
}
24、用户注册
(1)自定义异常类UsernameAlreadyExistsException(用户名已存在异常)继承Exception。
(2)自定义异常类LoginFailException(登录失败异常)继承Exception。
(3)用户类User,包含用户名和密码属性,私有化,提供有参、无参构造器,提供get/set、toString
(4)用户管理类UserManager
① 包含如下成员变量:
private static User[] arr ; //存储已经注册的用户
private static int total; //存储实际注册的用户数量
② 包含无参构造器
③ 包含如下方法:
- public void checkUsernameExists(String username):检查用户名是否已经存在,如果已经存在抛出UsernameAlreadyExistsException(用户名已存在异常)。
- public void add(User user):添加新用户到arr数组中
- public void login(User user):判断用户名和密码是否正确,如果没有匹配的用户名和密码,就报LoginFailException(登录失败异常)
(5)测试类,实现如下运行效果
--------尚硅谷----------
1、注册
2、登录
3、退出
请选择:1
用户名:song
密码:123456
注册成功
--------尚硅谷----------
1、注册
2、登录
3、退出
请选择:1
用户名:song
用户名已存在
用户名:lin
密码:123456
注册成功
--------尚硅谷----------
1、注册
2、登录
3、退出
请选择:2
用户名:song
密码:123456
登录成功
--------尚硅谷----------
1、注册
2、登录
3、退出
请选择:2
用户名:lin
密码:654321
com.atguigu.homework10.LoginFailException: 登录失败
at com.atguigu.homework10.UserManager.login(UserManager.java:36)
at com.atguigu.homework10.Exercise24.login(TestUser.java:42)
at com.atguigu.homework10.Exercise24.main(TestUser.java:23)
--------尚硅谷----------
1、注册
2、登录
3、退出
请选择:3
public class UsernameAlreadyExistsException extends Exception {
public UsernameAlreadyExistsException() {
}
public UsernameAlreadyExistsException(String message) {
super(message);
}
}
public class LoginFailException extends Exception {
public LoginFailException() {
}
public LoginFailException(String message) {
super(message);
}
}
public class User {
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
public class UserManager {
private static User[] arr ;
private static int total;
public UserManager(){
arr = new User[5];
}
public void checkUsernameExists(String username) throws UsernameAlreadyExistsException {
for (int i = 0; i < total; i++) {
if(username.equals(arr[i].getUsername())){
throw new UsernameAlreadyExistsException("用户名已存在");
}
}
}
public void add(User user){
if(total>=arr.length){
User[] newArr = new User[arr.length + (arr.length>>2)];
for (int i = 0; i < total; i++) {
newArr[i] = arr[i];
}
arr = newArr;
}
arr[total++] = user;
}
public void login(User user) throws LoginFailException {
for (int i = 0; i < total; i++) {
if(user.getUsername().equals(arr[i].getUsername()) && user.getPassword().equals(arr[i].getPassword())){
return;
}
}
throw new LoginFailException("登录失败");
}
}
public class Exercise24{
private static Scanner input = new Scanner(System.in);
private static UserManager um = new UserManager();
public static void main(String[] args) {
boolean flag = true;
while(flag){
System.out.println("--------尚硅谷----------");
System.out.println("\t\t1、注册");
System.out.println("\t\t2、登录");
System.out.println("\t\t3、退出");
System.out.print("\t请选择:");
int select = input.nextInt();
switch (select){
case 1:
regist();
break;
case 2:
login();
break;
case 3:
flag = false;
}
}
input.close();
}
private static void login() {
System.out.print("用户名:");
String username = input.next();
System.out.print("密码:");
String password = input.next();
User user = new User(username,password);
try {
um.login(user);
System.out.println("登录成功");
} catch (LoginFailException e) {
e.printStackTrace();
}
}
private static void regist(){
String username;
while(true) {
System.out.print("用户名:");
username = input.next();
try {
um.checkUsernameExists(username);
break;
} catch (UsernameAlreadyExistsException e) {
System.err.println(e.getMessage());
input.nextLine();
}
}
System.out.print("密码:");
String password = input.next();
User user = new User(username,password);
um.add(user);
System.out.println("注册成功");
}
}
版权声明:如无特别声明,本站收集的文章归 HuaJi66/Others 所有。 如有侵权,请联系删除。
联系邮箱: GenshinTimeStamp@outlook.com
本文标题:《 练习-第09章_异常处理.md 》
本文链接:/java/%E7%BB%83%E4%B9%A0%E9%A2%98/%E7%AC%AC09%E7%AB%A0_%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86.html