异常、常见异常、throw、throws、finally、线程

一、异常
1.定义:程序正在运行中,出现非正常的情况,导致JVM的非正常停止;
2.java面向对象中,异常本身是一个类,产生异常时创建异常对象并抛出异常,java处理异常的方式时中断处理,
注:异常并不是语法错误,错误时不执行的。
3.异常包所在地:
java.lang.Throwable:此类是java中所有错误和异常的超类
java.lang.Error:错误
java.lang.Exception:异常
4.编译时异常:写程序的时候报红:例如IOException FileNotFoundException ParseException
5.运行时异常:(RunTImeException):控制台报红 例如:ArithmeticException、ClassCastException、illegalArgumentException IndexOutOfBoundsExpection(ArrayIndexOutOfBoundsExpection、 StringIndexOutOfBoundsException、NoSuchElementException 、NullPointException)
注:异常时手写的,程序员必备异常出现和解决方法,切记,切记,切记
6.异常出现与解决方法:基础的
NullPointerException:空指针异常,未经过初始化对象或者不存在对象,出处:创建图片、调用数组,比如未初始化、创建图片路径错误,对数组操作出现空指针
ArithmeticException:数学运算异常,出处:比如出现了除以0的运算,就会出现这个异常,解决:好好检查程序中设计到数学运算的地方、公式。
ArrayIndexOutOfBoundsException:数组下标越界,出处:多处于数组的使用,看看数组的长度是不是超出了范围,一般很难错,但是如果是把数组赋值给其他变量操作时,需要注意,另一种情况就是,主函数的数组长度时通过某些特定的方式决定的,没有实现声明,如果报异常就看看数组的length。
IllegalArgumentException:方法参数错误,一旦出现这个错误最先查看的就是参数的传递过程中是否出现了异常,

7.throw关键字
作用:在指定地方抛出异常
格式:throw new XXXException(“异常抛出的原因”)
注意:throw必须写在方法内部
throw后面new的对象必须时Exception或者Exception的子类
throw抛出指定的异常,就要处理这个异常对象
抛出的异常对象时RunTimeException或者RunTImeException的子类对象,可以不处理,交给JVM处理,(JVM打印异常对象到控制台,并中断程序,)
抛出的异常的对象时编译器异常,必须手动处理throws,try…catch

8.throws:异常处理的第一种方式,交给别人处理
作用:会把方法内部抛出的异常对象抛给方法的调用者处理,最终交给JVM处理,中断程序
使用方式:在方法的声明时处理,
修饰符 返回值 方法名 (参数列表) throws AXXXException,BXXXException{ throws new AXXXException(“异常产生的原因”);
throws new BXXXException(“异常产生的原因”);}
注意:throws必须写在方法的声明处
throws后面声明的异常必须时Exception或者Exception的子类
如果方法内部抛出多个异常对象,throws后面必须声明多个异常
如果方法内部抛出了多个异常对象又子父类关系,throws后面直接声明父类异常即可
调用了一个声明抛出异常的方法,必须要处理

9.try…catch:异常处理的第二种方式,自己处理异常
格式:try{可能出现异常的代码}catch(定义一个异常类型的变量,用来接收try抛出的异常对象){异常的处理逻辑,如何处理异常逻辑,在工作中,会把异常的信息记录在一个日志中}…catch(异常类型 变量名)
注意:try抛出多个异常对象的时候,可以使用多个catch处理异常对象
如果try中产生了异常,那么就会运行catch中异常的处理逻辑,执行完毕,继续执行try…catch后面的代码
如果try中没有产生异常,就不会执行catch中异常的处理逻辑,执行try中的代码完继续执行try…catch

10.finally代码块:
格式:try{]catch(){}finally{一定会执行的代码}
注意:finally不能单独使用,只能和try一起使用
finally一般用于资源的释放(回收),无论程序是否出现异常,最后都要释放资源(多用于IO流)

11.很有意思的一道题:final finally finalize()的区别:
final:修饰符,修饰变量变成常量,修饰方法不能被重写,修饰类不能被继承
finally:语句块,一定会执行语句块中的代码
finalize():方法,垃圾回收的时候,JVM调用的方法,不需要程序员手动调用。

12*异常处理的注意事项
1)多个异常使用捕获处理
多个异常分别处理
多个异常,一次捕获,一次处理
多个异常,捕获一次,处理一次
2)finally{}中又return语句,永远返回finally中的结果,注意避免此情况
3)如果父类抛出多个异常,子类重写父类方法的时候,抛出和父类相同的异常或者是父类异常的子类或者不抛出异常,
父类方法没有抛出异常,子类重写父类方法的时候有异常也不能抛出异常,此实子类只能捕获try…catch异常

12自定义异常:
1)自定义异常一般都以Exception结尾,说明该类是异常类
2)必须继承Exception或者RuntimeException
3)必须添加一个空参数的构造放啊
4)必须添加一个带异常信息的构造方法

二、线程
1.并发:指两个或者以上事件在同一时间段内发生
2.并行:指两个或以上事件同一时刻同时发生
3.线程和进程
1)进程:指在一个内存中运行的应用程序,每个进程都有一个独立的内存空间,一个应该程序可以同时运行多个进程,进程也是程序的一次执行过程,是系统运行的基本单位;系统运行一个程序就是一个程序从创建、运行到消亡的过程
2)线程:是进程的执行单元,负责当前进程中程序的执行,一个进程至少一个线程,一个进程中可以有多个线程,称为多线程程序。总之,一个程序运行至少有一个进程,一个进程中可以包含多个线程
4.线程调度
1)分时调用:所有线程轮流使用cpu的使用权,平均分配每个线程占用cpu的时间
2)抢占式调用
优先让优先级高的线程使用CPU,如果线程的优先级相同,那么随机选择一个线程,注:java使用的是抢占式调度
抢占式调度:大部分操作系统都是支持多线程,操作系统机会都是支持同时运行多个程序的,实际上,CPU使用抢占式调度模式在多个线程进行着告高速的切换,大于与CPU的一个核而言,某个时刻,只能执行一个线程,而CPU在多个线程间切换速度相对我们的感觉要快,看上去就是在同一时刻运行,其实,多线程并不是没有提高运行速度,能够提高程序运行效率,让CPU使用效率更高。
3)线程创建
首先需要创建一个线程类,类继承Thread类,重写Thread类里面的run方法,接着创建线程类的run’方法,创建线程类的对象,调用Thread类中的start()启动线程
注意:加入多线程之后,JVM内存:方法区。堆,主栈(main方法里面的代码),分支栈(自定义线程中的代码)

昨日习题
一、请简述Map 的特点。
首先Map集合和Collection集合没有任何关系,其次Map集合是双列集合,就是说Map集合的元素有又两个值确定一个元素,分别是key、value键值对的形式存储,一个键值对确定一个元素;对于key和value存储的是java的内存地址,所以Map存储的值都是无序不重复的,对于键值对key和value,是一一对应的,数据类型可以一致,也可以不一致,k值不可以重复,v值可以,都是无序的。
二、说出Entry键值对对象遍历Map集合的原理。
关于Entry键值对对象遍历Map集合的原理:这里需要创建Set接口,在写出Map接口中的Entry里面的数据类型,最后还有调用entry这个重要的方法,其次只需要使用getKey()和getValue()返回集合的键值就行了,说的比
四、请使用Map集合的方法完成添加元素,根据键删除,以及根据键获取值操作。
package Week9;

import java.util.HashMap;
import java.util.Map;

public class demo3 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(1,“百里守约”);
map.put(2,“宫本武藏”);
map.put(3,“娜可露露”);
System.out.println(“添加:”+map);
System.out.println(“删除:”+map.remove(1));
for (String value : map.values()) {
System.out.println(value);
}
}
}
四、往一个Map集合中添加若干元素。获取Map中的所有value,并使用增强for和迭代器遍历输出每个value。
package Week9;

import java.util.HashMap;
import java.util.Map;

public class demo4 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(1,“貂蝉”);
map.put(2,“羞花”);
map.put(3,“沉鱼”);
map.put(4,“落雁”);
System.out.println(map.values());
for (Integer in : map.keySet()) {
System.out.print(map.get(in)+" ");
}
}
}
五、请使用Map集合存储自定义数据类型Car做键,对应的价格做值。并使用keySet和entrySet两种方式遍历Map集合。
package Week9;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class demo5 {
public static void main(String[] args) {
demo5Car car1 = new demo5Car(“劳斯莱斯”);
demo5Car car2 = new demo5Car(“法拉利”);
demo5Car car3 = new demo5Car(“宝马”);

    Map<demo5Car, Integer> map = new HashMap<>();
    map.put(car1,999999999);
    map.put(car2,2000000000);
    map.put(car3,223564758);

    for (demo5Car car : map.keySet()) {
        demo5Car key = car;
        Integer value = map.get(car);
        System.out.println(key+"="+value);
    }

    Set<Map.Entry<demo5Car,Integer>> set = map.entrySet();
    for (Map.Entry<demo5Car, Integer> entry : set) {
        demo5Car key = entry.getKey();
        Integer value = entry.getValue();
        System.out.println(key+"="+value);
    }
}

}

六、现在有一个map集合如下:
Map<Integer,String> map = new HashMap<Integer, String>();
map.put(1, “张三丰”);
map.put(2, “周芷若”);
map.put(3, “汪峰”);
map.put(4, “灭绝师太”);
要求:
1.遍历集合,并将序号与对应人名打印。
2.向该map集合中插入一个编码为5姓名为李晓红的信息
3.移除该map中的编号为1的信息
4.将map集合中编号为2的姓名信息修改为"周林"
package Week9;

import java.security.spec.RSAOtherPrimeInfo;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class demo6 {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(1, “张三丰”);
map.put(2, “周芷若”);
map.put(3, “汪峰”);
map.put(4, “灭绝师太”);
Set<Map.Entry<Integer,String>> set = map.entrySet();
for (Map.Entry<Integer, String> entry : set) {
Integer key = entry.getKey();
String value = entry.getValue();
System.out.println(key+"="+ value);
}
map.put(5,“李晓红”);
System.out.println(map);
System.out.println(map.remove(1));
System.out.println(map.put(2,“周林”));
}
}
七、有2个数组,第一个数组内容为:[黑龙江省,浙江省,江西省,广东省,福建省],第二个数组为:[哈尔滨,杭州,南昌,广州,福州],将第一个数组元素作为key,第二个数组元素作为value存储到Map集合中。如{黑龙江省=哈尔滨, 浙江省=杭州, …}
package Week9;

import java.util.HashMap;
import java.util.Map;

public class demo7 {
public static void main(String[] args) {
String[] str1 = {“黑龙江省”,“浙江省”,“江西省”,“广东省”,“福建省”};
String[] str2 = {“哈尔滨”,“杭州”,“南昌”,“广州”,“福州”};
Map<String,String> map = new HashMap<>();
for (String key : str1) {
for (String value : str2) {
map.put(key,value);
}
}
System.out.println(map);
}
}

八、定义一个泛型为String类型的List集合,统计该集合中每个字符(注意,不是字符串)出现的次数。例如:集合中有”abc”、”bcd”两个元素,程序最终输出结果为:“a = 1,b = 2,c = 2,d = 1”。
package Week9;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class demo9 {
public static void main(String[] args) {
String str1 = “abc”;
String str2 = “bcd”;
String str = str1+str2;

    Map<Character,Integer> map = new HashMap<>();
    for (int i = 0; i < str.length(); i++) {
        char chars = str.charAt(i);
        if (!map.containsKey(chars)){ //判断是否包含内部的字符串
            map.put(chars,1);
        }else {
            Integer count = map.get(chars);
            map.put(chars,++count);
        }
    }
    System.out.println(map);
}

}
九、利用Map,完成下面的功能:从命令行读入一个字符串,表示一个年份,输出该年的世界杯冠军是哪支球队。如果该 年没有举办世界杯,则输出:没有举办世界杯。
package Week9;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class demo9 {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put(“1930”,“乌拉圭”);
map.put(“1934”,“意大利”);
map.put(“1938”,“意大利”);
map.put(“1950”,“乌拉圭”);
map.put(“1954”,“西德”);
map.put(“1958”,“巴西”);
map.put(“1962”,“巴西”);
map.put(“1966”,“英格兰”);
map.put(“1970”,“巴西”);
map.put(“1974”,“西德”);

    Scanner sc = new Scanner(System.in);
    System.out.print("请输入年份");
    String str = sc.next();
    for (int i = 0; i < map.size(); i++) {
        if(!map.keySet().equals(str)){
            System.out.println(str+"年获得冠军的球队是:"+map.get(str));
            break;
        }else {
            System.out.println("本年没有获得冠军的队伍!");
        }
    }
}

}
十、在原有世界杯Map 的基础上,增加如下功能: 读入一支球队的名字,输出该球队夺冠的年份列表。 例如,读入“巴西”,应当输出 1958 1962 1970 1994 2002 读入“荷兰”,应当输出 没有获得过世界杯
package Week9;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

public class demo9 {
public static void main(String[] args) {
Map<String,String> map = new HashMap<>();
map.put(“1930”,“乌拉圭”);
map.put(“1934”,“意大利”);
map.put(“1938”,“意大利”);
map.put(“1950”,“乌拉圭”);
map.put(“1954”,“西德”);
map.put(“1958”,“巴西”);
map.put(“1962”,“巴西”);
map.put(“1966”,“英格兰”);
map.put(“1970”,“巴西”);
map.put(“1974”,“西德”);

    Scanner sc = new Scanner(System.in);
    Scanner scanner = new Scanner(System.in);
    System.out.print("请输入年份");
    String str = sc.next();
    for (int i = 0; i < map.size(); i++) {
        if(!map.keySet().equals(str)){
            System.out.println(str+"年获得冠军的球队是:"+map.get(str));

            System.out.print("请输入获得冠军的国家:");
            String string = scanner.next();

            if (map.containsValue(string)){
                System.out.println(string+"球队获得冠军的年份有:");
                for (String key : map.keySet()) {
                    if (map.get(key).contains(string)){
                        System.out.println(key);
                    }
                }
            }else {
                System.out.println("他们没有获得冠军过");
            }

            break;
        }else {
            System.out.println("本年没有获得冠军的队伍!");
        }
    }
}

}

1.描述异常体系,个人对Erro和Exception的理解,以及对运行时异常(RunTime Exception)的理解
2.throw和throws的区别
3.异常的处理方式
4.常见异常及报错原因
5.并行和并发的概念
6.进程、线程是什么,有什么联系
7.请使用代码实现每一个学生(Student)都有学号,姓名和分数,分数永远不能为负数如果老师给学生赋值一个负数,抛出一个自定异常
8.创建多线程对象,开启多线程。在子线程中输出1-100之间的偶数,主线程输出1-100之间的奇数。
9.在一款角色扮演游戏中,每一个人都会有名字和生命值;角色的生命值不能为负数要求:当一个人物的生命值为负数的时候需要抛出自定的异常
10.创建三个子线程,在每个线程中开启10万次的循环,线程1循环中将循环自增变量i赋值给Integer类型变量 a,线程2循环中将字符串"法赛特公司"赋值给String类型变量b,线程3循环中将字符串"法赛特公司"和循环自增变量i拼接后赋值给String类型变量c分别计算三个线程完成任务所用的毫秒值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值