异常
1. 异常处理
1.1 Throwable类
Throwable类是Java中所有异常和错误的基类,规定一些操作方法
构造方法 Constructor
Throwable();
创建一个Throwable类对象,异常信息为null
Throwable(String message);
创建一个Throwable类对象,使用message信息作为当前异常/错误提示内容
成员方法:
String toString();
返回当前Throwable类对象简要信息描述
String getMessage();
返回当前Throwable类对象中的message信息
void printStackTrace();
展示当前错误/异常的前因后果
package com. qfedu. a_throwable ;
public class Demo1 {
public static void main ( String [ ] args) {
Throwable throwable = new Throwable ( "单身狗异常" ) ;
System . out. println ( "toString : " + throwable. toString ( ) ) ;
System . out. println ( "getMessage : " + throwable. getMessage ( ) ) ;
test ( ) ;
}
public static void test ( ) {
new Throwable ( "前因后果" ) . printStackTrace ( ) ;
}
}
1.2异常结构
Throwable 异常/错误的基类
--| Exception 异常
--| Error 错误
Exception和Error区别
1. 结尾不同
ArrayIndexOutOfBoundsException 数组下标越界异常
StringIndexOutOfBoundsException 字符串下标越界异常
NullPointerException 空指针异常
OutOfMemoryError 内存溢出错误
2. 异常可以处置,错误有且只能避免
1.3 异常处理
和生活中类似
1. 小问题门诊可以处理,捕获
2. 小诊所无法处理,让你去大医院,抛出
1.3.1 捕获
两种结构
try {
} catch (异常类型) {
处理当前异常的方式
}
try {
} catch () {
} finally {
}
1. 在try 大括号里面是有可能出现异常的代码
2. catch之后小括号是异常类型,catch大括号中是对应当前异常类型的处理方式
3. finally大括号中是无论当前代码是否出现异常,都一定会执行的代码,通常用于资源关闭问题。文件操作,数据库操作,网络数据传输操作。。。
1.3.2 抛出
抛出异常:报红直接使用快捷键Alt + enter键修复
注意方法声明上抛出异常使用的是throws
方法内抛出异常使用的是throw
异常和泛型
1. 异常
1.1 抛出异常
使用关键字:
throw 在方法中抛出对应异常对象
throws 在方法声明位置告知调用者,当前方法抛出哪些异常
package com. qfedu. a_exception ;
public class Demo1 {
public static void main ( String [ ] args) {
test ( 100 , 10 , null ) ;
}
public static void test ( int num1, int num2, int [ ] arr)
throws ArithmeticException , NullPointerException {
if ( 0 == num2) {
throw new ArithmeticException ( "除数不能为0" ) ;
}
if ( null == arr) {
throw new NullPointerException ( "数组不能为null" ) ;
}
int ret = num1 / num2;
System . out. println ( "ret : " + ret) ;
arr[ 0 ] = 10 ;
System . out. println ( arr[ 0 ] ) ;
}
}
1.2 抛出和捕获
1.3 自定义异常
开发中的异常多数情况下是在语法约束的情况下,来处理或者描述语法异常情况。
但是不能满足生活化 业务逻辑中出现的异常。
SingleDog异常,网线GG异常,兜里没钱异常...
自定义异常格式
class MyException extends Exception {
// 需要完成两个构造方法
// 无参数构造方法
// 有参数构造方法(String message)
}
package com. qfedu. a_exception ;
@SuppressWarnings ( "all" )
class SingleDogException extends Exception {
public SingleDogException ( ) { }
public SingleDogException ( String message) {
super ( message) ;
}
}
public class Demo2 {
public static void main ( String [ ] args)
throws SingleDogException {
try {
buyOneFreeOne ( false ) ;
} catch ( SingleDogException e) {
e. printStackTrace ( ) ;
}
buyOneFreeOne ( false ) ;
}
public static void buyOneFreeOne ( boolean single)
throws SingleDogException {
if ( single) {
throw new SingleDogException ( "路见不平一声吼,你还没有女朋友" ) ;
}
System . out. println ( "法拉利买一送一(5号南孚聚能环)" ) ;
}
}
2. 泛型
2.1 泛型的基本格式和作用
格式:
<自定义无意义单个大写英文字母占位符>
<K> <V> <T> <E>
泛型:
泛泛而谈的类型,可以转换成任意类型。
万能牌,想什么是什么!!!
2.2 泛型在方法中使用
格式:
权限修饰符 [静态修饰] <泛型声明> 返回值类型 方法名(形式参数列表) {
}
要求:
1. 【重点】参数列表必须有一个参数类型是对应方法声明的自定义泛型。
在方法中泛型对应的具体数据类型 是通过该实际参数类型来进行约束操作。
2. 返回值类型可以使用自定义泛型。
3. 在方法体中也可以使用自定义泛型。
package com. qfedu. b ;
public class Demo1 {
public static void main ( String [ ] args) {
String str1 = test ( "泛型" ) ;
Demo1 d1 = test ( new Demo1 ( ) ) ;
Integer i = test ( 10 ) ;
}
public static < T > T test ( T t) {
return t;
}
}
package com. qfedu. b ;
public class Demo2 {
public static void main ( String [ ] args) {
Integer [ ] intArr = { 1 , 3 , 5 , 7 , 9 , 2 , 4 , 6 , 8 , 10 } ;
printArray ( intArr) ;
System . out. println ( ) ;
Float [ ] floatArr = { 3.5F , 5.4F , 5.5F , 5.6F , 3.1415926F } ;
printArray ( floatArr) ;
System . out. println ( ) ;
String [ ] stringArr = { "ABCDEFG" , "HIJKLMN" , "OPQ, RST" , "UVW, XYZ" } ;
printArray ( stringArr) ;
}
public static < T > void printArray ( T [ ] arr) {
for ( int i = 0 ; i < arr. length; i++ ) {
System . out. println ( arr[ i] ) ;
}
}
}
2.3 泛型在类中使用
格式:
class 类名<自定义无意义单个大写英文字母占位符> {
类内的成员方法可以使用自定义泛型
}
package com. qfedu. b ;
class TypeA < T > {
public void test ( T t) {
System . out. println ( t. getClass ( ) ) ;
}
public T getType ( T t) {
return t;
}
public static < E > E testStatic ( E e) {
return e;
}
}
public class Demo3 {
public static void main ( String [ ] args) {
TypeA < String > t1 = new TypeA < String > ( ) ;
String string = t1. getType ( "泛型对应具体数据类型约束" ) ;
t1. test ( "String类型" ) ;
TypeA < Demo1 > t2 = new TypeA < Demo1 > ( ) ;
t2. test ( new Demo1 ( ) ) ;
Demo1 type = t2. getType ( new Demo1 ( ) ) ;
TypeA typeA = new TypeA ( ) ;
typeA. test ( 1 ) ;
typeA. test ( 3.14 ) ;
typeA. test ( "21312" ) ;
typeA. test ( new Demo1 ( ) ) ;
}
}
泛型和集合
1. 泛型
1.1 泛型在接口中使用
格式:
interface A<自定义无意义单个英文大写字母占位符> {
成员变量缺省缺省属性:
public static final 定义时必须初始化,
泛型对应的数据,如何初始化???泛型不是具体数据类型,无法进行初始化
操作,并且接口中的成员变量是一个带有名字的常量,需要明确数据类型。
成员方法可以使用自定义泛型。
}
package com. qfedu. a ;
interface A < T > {
void test ( T t) ;
public default void testDefault ( T t) {
System . out. println ( t. getClass ( ) ) ;
}
}
class TypeA < T > implements A < T > {
@Override
public void test ( T t) {
System . out. println ( "test : " + t. getClass ( ) ) ;
}
}
class TypeB implements A < String > {
@Override
public void test ( String t) {
System . out. println ( t. getClass ( ) ) ;
}
}
public class Demo1 {
public static void main ( String [ ] args) {
TypeA < String > t1 = new TypeA < String > ( ) ;
t1. test ( "String" ) ;
t1. testDefault ( "String" ) ;
TypeA < Demo1 > t2 = new TypeA < Demo1 > ( ) ;
t2. test ( new Demo1 ( ) ) ;
t2. testDefault ( new Demo1 ( ) ) ;
TypeB typeB = new TypeB ( ) ;
typeB. test ( "妻管严" ) ;
typeB. testDefault ( "真·妻管严" ) ;
}
}
2. 集合【重点】
2.1 开发中对于集合的期望
统一数据类型,数据个数多个,目前管理方式有且只有数组,并且需要自行完成数组对应的操作方法。
1. 数组对应数据类型单一。不能满足多种数据类型的要求,和代码复用的要求
2. 数组操作对应的方法,没有统一规范,底层数组都对应一套方法,
3. 数组容量一旦确定,无法更改。
集合就可以解决以上问题!!!
1. 支持所有数据类型,但是在数据类型多样化的情况下,又没有丢失数据类型一致化要求。
2. 方法众多,工具方便,使用快捷 ==> 【抄】
3. 数组容量问题有多种方式解决,可以适应各种条件。
4. 集合提供了多种存储模型,可以根据当前数据的操作需要来选择合适的方式。
2.2 集合的基本结构
interface Collection<E> Java中所有集合的总接口
--| interface List<E> 特征: 有序,可重复
----| class ArrayList<E>
底层存储数据的方式是数组形式,提供对应操作方式。特点 增删慢,查询快
----| class LinkedList<E>
底层存储数据的结果是双向链表,特点 增删快,查询慢
----| class Vector<E>
是ArrayList线程安全版,效率低于ArrayList,线程安全性高
--| interface Set<E> 特征: 无序,不可重复
----| class HashSet<E>
底层数据采用哈希(Hash)表结构,存储效率极高
----| class TreeSet<E>
底层数据采用树形结构存储,数据存储需要有对应的比较方式
2.3 Collection 接口下的常用方法
增:
add(E e);
添加用户指定数据类型到当前Collection集合中
addAll(Collection<? extends E> c);
添加参数集合到当前集合中,要求参数集合中保存的数据类型是E类型本身或者其子类对象。
删:
remove(Object obj);
删除当前集合中用户指定的对象,对象类型为Object类型,不限制用户输入的数据
removeAll(Collection<?> c);
在当前调用方法的集合对象中,删除参数集合和当前集合的交集。参数集合中保存的数据类型不限制
retainAll(Collection<?> c);
在当前调用方法的集合对象中,保留参数集合和当前集合的交集。参数集合中保存的数据类型不限制
clear();
删除集合中所有元素。清空集合。
查:
int size();
当前集合中有效元素个数
boolean isEmpty();
判断当前集合是否为空
boolean contains(Object obj);
判断当前集合中是否包含对应指定元素
boolean containsAll(Collection<?> c);
判断当前参数集合是否是当前集合的子集合
Object[] toArray();
返回当前集合中所有元素的Object类型数组
【补充知识点 泛型的上限】
<? extends E>
<> ==> 泛型
? 通配符
extends 继承
E 自定义无意义大写单个英文字母占位符
class Animal
class Tiger extends Animal
class Panda extends Animal
class SingleDog extends Animal
<? extends E>
要求当前类型是E类型本身,或者是E类型的子类,泛型的上限
2.4 Collection Iterator使用
2.4.1 Iterator涉及到的方法
Iterator涉及到的方法:
Iterator<E> iterator();
通过集合对象调用,获取当前集合对应的Iterator对象,Iterator对象的泛型和对应集合中存储元素一致
E next();
获取当前Iterator指向元素,并且将Iterator指向下一个元素。、
boolean hasNext();
判断当前Iterator对象是否可以继续获取元素。
void remove();
删除,【有坑】
1. 删除元素有且只能是next取出元素
2. remove之前必须有一个next,不允许跨域其他next
2.4.2 资源冲突问题
package com. qfedu. b_collection ;
import java. util. ArrayList ;
import java. util. Collection ;
import java. util. Iterator ;
public class Demo4 {
public static void main ( String [ ] args) {
Collection < String > c1 = new ArrayList < String > ( ) ;
c1. add ( "螺蛳粉" ) ;
c1. add ( "炒拉条" ) ;
c1. add ( "烤面筋" ) ;
c1. add ( "黄焖鸡米饭" ) ;
c1. add ( "热干面" ) ;
c1. add ( "烩面" ) ;
Iterator < String > it = c1. iterator ( ) ;
System . out. println ( it. next ( ) ) ;
System . out. println ( it. next ( ) ) ;
System . out. println ( it. next ( ) ) ;
c1. remove ( "烩面" ) ;
System . out. println ( it. next ( ) ) ;
System . out. println ( it. next ( ) ) ;
System . out. println ( it. next ( ) ) ;
}
}