异常和泛型,泛型和集合

异常

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());
		
//		throwable.printStackTrace();
		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;

/*
 * 抛出异常的注意事项:
 * 		1. 在方法中使用throw根据对应条件抛出对应异常,同时需要在方法的声明位置使用
 * 		throws关键字告知调用者这里抛出哪些异常
 * 		2. 在同一个条件内有且只能抛出一个异常,因为代码从throw语句不再执行。
 * 		3. 如果需要在方法中抛出多个异常,需要多个条件来辅助问题
 * 		4. 调用方法带有异常抛出,需要处理当前异常。可以再次抛出或者捕获处理,如果当前
 * 		异常是RuntimeException本身或者其子类,可以考虑交给JVM自行处理【红色警告】
 * 
 * 什么时候抛出异常,什么时候捕获异常???
 */
public class Demo1 {
	public static void main(String[] args) {
		test(100, 10, null);
	}
	
	/**
	 * 测试方法
	 * 
	 * @param num1 int类型数据
	 * @param num2 int类型数据
	 * @param arr  int类型数组
	 * @throws ArithmeticException 除数不能为0
	 * @throws NullPointerException 数组不能为null
	 */
	public static void test(int num1, int num2, int[] arr) 
			throws ArithmeticException, NullPointerException {
		/* 参数合法性判断
		if (0 == num2 || null == arr) {
			System.out.println("用户传入参数不合法!!!");
			return;
		}
		*/
		// 使用throw抛出异常
		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;

/**
 * 完成自定义异常,继承Exception类,自定义异常要求类名Exception结尾
 * 
 * @author Anonymous
 */
@SuppressWarnings("all")
class SingleDogException extends Exception {
	// 无参数构造方法
	public SingleDogException() {}
	
	/**
	 * 有参数构造方法 提供异常信息,供后期代码操作使用
	 * @param message 异常信息
	 */
	public SingleDogException(String message) {
		/*
		 * 通过super关键字来调用父类构造方法
		 */
		super(message);
	}
}

public class Demo2 {
	public static void main(String[] args) 
        throws SingleDogException {
		try {
			// 捕获处理当前抛出异常的方法
			buyOneFreeOne(false);
		} catch (SingleDogException e) {
			// TODO Auto-generated catch block
			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 返回值类型 String
		String str1 = test("泛型");
		
		// 参数类型 Demo1 返回值类型 Demo1
		Demo1 d1 = test(new Demo1());
		
		// 参数类型是int类型,返回值类型也是int类型
		// 这里使用的是包装类 Integer 基本类型看作是引用数据类型
		Integer i = test(10);
	}
	
	/**
	 * 测试方法
	 * 
	 * @param <T> 自定义泛型无意义单个大写字母占位符
	 * @param t   当前方法声明泛型对应树数据类型
	 * @return 当前方法声明的泛型。
	 */
	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);
	}
	
	/**
	 * 用于展示任意类型数组的方法
	 * 
	 * @param <T> 泛型占位符
	 * @param arr 任意类型数组
	 */
	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;

/**
 * 声明一个类,带有自定义泛型
 * @author Anonymous
 *
 * @param <T> 自定义泛型占位符,可以提供给类内的成员方法使用
 */
class TypeA<T> {
	/**
	 * 当前方法的参数类型是和类名一致的自定义泛型
	 * 
	 * @param t 和类名声明一致的泛型
	 */
	public void test(T t) {
		// t.getClass() 获取当前对象对应的完整包名.类名
		System.out.println(t.getClass());
	}
	
	/**
	 * 当前方法的参数和返回值类型都是和类名声明一致的自定义泛型
	 * 
	 * @param t 和类名一致的自定义泛型
	 * @return 返回值类型也是当前类名声明的自定义泛型
	 */
	public T getType(T t) {
		return t;
	}
	
	/*
	 * 静态成员方法是否可以使用类名声明的泛型
	 * 
	 * 静态成员方法需要随着类文件的加载直接定义在内存的方法区,并且已经具有执行能力。
	 * 需要准备所有的 返回值类型,方法名,形式参数列表(参数个数,顺序,类型)
	 * 
	 * 类名代用的自定义泛型声明,是需要在类对象创建过程中进行约束操作的。
	 * 
	 * 静态成员方法和类名声明泛型冲突!!!两者生存周期和作用时间不同。
	 */
	// public static T testStatic(T t) {
	//     return t;
	// }
	
	/*
	 * 静态成员方法自娱自乐定义泛型,自行使用,泛型对应的具体数据类型在调用时
	 * 通过参数类型明确约束。
	 * 
	 * 自娱自乐定义泛型,不要和类名一致!!!避免造成阅读压力
	 */
	public static <E> E testStatic(E e) {
		return e;
	}
}

public class Demo3 {
	public static void main(String[] args) {
		/*
		 * 创建TypeA对象,t1 告知编译器,当前t1对象对应的所有泛型具体数据类型
		 * 为String类型。这里进行的泛型【具体数据类型约束】
		 * 
		 * 泛型约束类:
		 * 		1. 满足当前类中的内容可以满足多样性
		 * 		2. 又可以在具体数据类型约束之后,满足数据类型一致化要求
		 */
		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类对象过程中,没有约束泛型对应的具体数据类型
		 * 
		 * 【不建议使用】,如果没有明确泛型约束,所有泛型占位符对应数据类型全部变为Object类型
		 * 不能最大化的发挥泛型的作用,【不建议使用】
		 */
		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());
	}
}

/*
 * 类遵从带有自定义泛型的接口,有两种模式
 * 		1. 自由模式
 * 		2. 妻管严模式
 */

/*
 * 自由模式
 * 在类名位置声明和接口中泛型一致的内容
 * 
 * 泛型对应的具体数据类型,是通过创建当前类对象完成的。
 */
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对象
		Iterator<String> it = c1.iterator();
		
		System.out.println(it.next());
		System.out.println(it.next());
		System.out.println(it.next());
		
		c1.remove("烩面");
		
		/*
		 * java.util.ConcurrentModificationException 
		 * 并发修改异常
		 * 在Iterator遍历集合的过程中,对集合元素进行修改删除操作,会
		 * 导致当前Iterator一脸懵逼,WTH。
		 * 
		 * 多线程操作共享数据,导致的并发冲突
		 * 	多线程 : 集合对象本身,和Iterator对象共同操作集合数据
		 * 	共享数据: 集合内容
		 * 	冲突:	 一方修改数据,并未告知对方、
		 * 	阈值
		 */
		System.out.println(it.next());
		System.out.println(it.next());
		System.out.println(it.next());
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值