以下内容为之前的补充以及后续的扩展
静态内部类完成单例
/*** 编写静态内部类完成单例模式创建
* 线程安全问题: 天然线程安全
* 延迟加载: 能做到延迟加载
* 类何时被加载: 调用静态内容 创建对象
* 类加载的时候 首先将静态内容加载大内存中
* @author wawjy
*/
public class Single {
static class SingleHolder{
private static Single single = new Single();
}
private Single() {
}
public static Single getInstance() {
return SingleHolder.single;
}
public static void add() {
}
public static void main(String[] args) {
Single s1 = getInstance();
Single s2 = getInstance();
System.out.println(s1);
System.out.println(s2);
Single.add();
Single s3 = getInstance();
} }
局部内部类
/*** 局部内部类:
* 定义在方法中的类 只能当前方法使用
* 一定程度减少内存开销 但是复用性是及其低的
* @author wawjy
**/
public class Test03 {
public static void main(String[] args) {
}
public static void info() {
class Inner{
}
}
}
匿名内部类
比较器的简单介绍
package com.mage.inner;
import java.util.Comparator;
/*
*
* 匿名内部类
*
* 两种比较的接口:
* 内部比较器 按照字典序列来比
* java.lang.Compareable 比较大小
* 外部比较器 自己定义比较规则
* java.util.Comparator
*
*
*
*/
public class Test01 {
public static void main(String[] args) {
//比较两个字符串的大小
String str1 = "acde";
String str2 = "b";
if(str1.compareTo(str2)>0) {
System.out.println(str1);
}else if(str1.compareTo(str2)<0) {
System.out.println(str1);
}else {
System.out.println("相等");
}
//创建比较器对象
Compare com = new Compare();
int num = com.compare(str1, str2);
if(num>0) {
System.out.println(str2);
}else if(num==0) {
System.out.println("相等");
}else {
System.out.println(str1);
}
}
}
class Compare implements Comparator{
//根据长度来比
@Override
public int compare(Object o1, Object o2) {
String str1 = (String)o1;
String str2 = (String)o2;
return str1.length()-str2.length();
}
}
匿名内部类
public class Test02 {
public static void main(String[] args) {
// 对于字符串按照按照字符串越短越大
Comparator com = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String str1 = (String) o1;
String str2 = (String) o2;
return -(str1.length() - str2.length());
}
};
String str1 = "a";
String str2 = "sdsd";
System.out.println(com.compare(str1, str2));
/*
* 该段代码就是匿名内部类 new Comparator() {
*
* @Override public int compare(Object o1, Object o2) { String str1 =(String)o1;
* String str2 = (String)o2; return -(str1.length()-str2.length()); } };
*/
// 对于匿名内部类还可以按以下使用
int sum = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String str1 = (String) o1;
String str2 = (String) o2;
return -(str1.length() - str2.length());
}
}.compare(str1, str2);
System.out.println(sum);
// jdk1.8后推出lambda表达式
//注意:lambda表达式只适合一个参数的接口实现类
Comparator com1 = (x, y) -> 1;
System.out.println(com1.compare(str1, str2));
// Comparator com1 = (x,y)->1;等价于
new Compare() {
public int compare(Object o1, Object o2) {
return 1;
}
};
}
}
策略模式
版本1:
/*
* 策略模式:
* 有一个数组 数组中存储的是Emp(员工)对象,员工有姓名 年龄 工资。
* 1:将数组中员工的工资大于2000 小于5000的员工信息罗列出来
* a:Emp类创建出来
*
*
*/
public class Test03 {
public static void main(String[] args) {
//通过带参构造器创建对象
Emplement emp1 = new Emplement("aaa",12, 1000);
Emplement emp2 = new Emplement("bbb",23, 3432);
Emplement emp3 = new Emplement("ccc",145, 5645);
Emplement emp4 = new Emplement("ddd",123, 10075670);
Emplement emp5 = new Emplement("eee",56, 3453);
//声明一个Emplement数组
Emplement[] emp = {emp1,emp2,emp3,emp4,emp5};
//将数组中的员工大于3000小于5000的员工展示出来
filterSal(emp);
//将数组中年龄大于18小于20的员工展示出来
filterAge(emp);
}
private static void filterAge(Emplement[] emp) {
//循环迭代emp数组
for(int i = 0;i<emp.length;i++) {
//获取数组中符合条件的元素
if(emp[i].getAge()>18&&emp[i].getAge()<50) {
System.out.println(emp[i]);
}
}
}
private static void filterSal(Emplement[] emp) {
//循环迭代emp数组
for(int i = 0;i<emp.length;i++) {
//获取数组中符合条件的元素
if(emp[i].getSal()>3000&&emp[i].getSal()<5000) {
System.out.println(emp[i]);
}
}
}
}
版本2
public class Test04 {
public static void main(String[] args) {
// 通过带参构造器创建对象
Emplement emp1 = new Emplement("张三", 22, 22);
Emplement emp2 = new Emplement("李四", 34, 19);
Emplement emp3 = new Emplement("王五", 546, 33);
Emplement emp4 = new Emplement("赵六", 234, 18);
Emplement emp5 = new Emplement("田七", 45, 21);
// 声明一个emp数组
Emplement[] emps = new Emplement[] { emp1, emp2, emp3, emp4, emp5 };
//创建一个过滤年龄的对象
Filter f = new FilterImple();
f.filterAge(emps);
}
}
版本3:
public class Test05 {
public static void main(String[] args) {
// 通过带参构造器创建对象
Emplement emp1 = new Emplement("张三", 22, 22);
Emplement emp2 = new Emplement("李四", 34, 19);
Emplement emp3 = new Emplement("王五", 546, 33);
Emplement emp4 = new Emplement("赵六", 234, 18);
Emplement emp5 = new Emplement("田七", 45, 21);
// 声明一个emp数组
Emplement[] emps = new Emplement[] { emp1, emp2, emp3, emp4, emp5 };
Filter f = new Filter() {
@Override
public void filterSal(Emplement[] emp) {
// 循环迭代emp数组
for (int i = 0; i < emp.length; i++) {
// 获取数组中符合条件的元素
if (emp[i].getSal() > 3000 && emp[i].getSal() < 5000) {
System.out.println(emp[i]);
}
}
}
@Override
public void filterAge(Emplement[] emp) {
// 循环迭代emp数组
for (int i = 0; i < emp.length; i++) {
// 获取数组中符合条件的元素
if (emp[i].getAge() > 18 && emp[i].getAge() < 50) {
System.out.println(emp[i]);
}
}
}
};
filter(emps, new Filter() {
@Override
public void filterSal(Emplement[] emp) {
// TODO Auto-generated method stub
}
@Override
public void filterAge(Emplement[] emp) {
// TODO Auto-generated method stub
}
});
}
public static void filter(Emplement[] emp, Filter f) {//Filter f = new FilterImpl();
f.filterAge(emp);
}
}
学生排序练习
student
/*
* 学号 姓名 录取分数 录取院校
*/
public class Student implements Comparable {
public static int selectNum = 0;
public static int selectSubNum = 0;
private int id;
private String name;
private int score;
private String school;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(int id, String name, int score, String school) {
super();
this.id = id;
this.name = name;
this.score = score;
this.school = school;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", score=" + score + ", school=" + school + "]";
}
@Override
public int compareTo(Object o) {
Student stu = (Student) o;
// 声明返回值类型
int result = 0;
switch (selectNum) {
case 1:
result = this.id - stu.id;
break;
case 2:
result = this.name.compareTo(stu.name);
break;
case 3:
result = this.score - stu.score;
break;
case 4:
result = this.school.compareTo(stu.name);
break;
}
if (selectSubNum != 1) {
result = -result;
}
return result;
}
}
view
/*
* 有一个数组 数组中存储了8个学生对象 每个学生都有学号 姓名 开始分数 录取院校
* 当程序启动,
* 1:显示学生所有信息
* 2:退出当前系统
* 用户输入1:
* 请输入需要排序的列
* 1学号 2 姓名 3 分数 4 录取院校
*
* 请输入排序规则
* 1升序 2倒序
* 用户输入2:
* 程序退出
*/
public class Test {
// 先声明一个学生数组
private static Student[] stus = new Student[5];
// 声明Scanner
static Scanner input = new Scanner(System.in);
// 将学生数组初始化
static {
init();
}
public static void main(String[] args) {
// 调用方法 显示给用户的提示信息
printMenu();
// 获取用户输入的值
int menuNum = getNum();
// 对于值进行判定
if (menuNum == 1) {
showAll();
orderFiled();
// 输出用户输入的值
int selectNum = getNum();
// 将值赋给student中变量
Student.selectNum = selectNum;
if (selectNum <= 4 && selectNum > 0) {
// 输出排序的规则
printSubRule();
// 获取用户输入的值
int selectSubNum = getNum();
// 将值赋给student中变量
Student.selectSubNum = selectSubNum;
if (selectSubNum == 1 || selectSubNum == 2) {
Arrays.sort(stus);
showAll();
} else {
System.out.println("你输入有误!");
}
} else {
System.out.println("你输入有误!");
}
} else if (menuNum == 2) {
System.exit(0);// 推出虚拟机
} else {
System.out.println("你输入有误!");
}
// 关闭所有资源
closeAll();
System.out.println("========================================================");
// 外部比较器
Arrays.sort(stus, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Student stu1 = (Student) o1;
Student stu2 = (Student) o2;
if (stu1.getName().compareTo(stu2.getName()) == 0) {
return stu1.getScore() - stu2.getScore();
} else {
return stu1.getName().compareTo(stu2.getName());
}
}
});
}
/*
* 排序字段
*/
private static void orderFiled() {
System.out.println("请输入排序字段");
System.out.println("1学号 2 姓名 3 分数 4 录取院校");
}
/*
* 排序规则
*/
private static void printSubRule() {
System.out.println("请输入你要排序的规则》》》》》》》");
System.out.println("1:升序");
System.out.println("2:降序");
}
/*
* 显示所有学生信息
*
*/
private static void showAll() {
System.out.println("\t学号\t姓名\t\t分数\t\t毕业院校");
for (Student stu : stus) {
System.out.println(stu);
}
}
/*
* 关闭所有资源
*/
private static void closeAll() {
if (input != null) {
input.close();
}
}
/*
* 获取用户从键盘输入的值
*/
private static int getNum() {
int menuNum = -1;
if (input.hasNextInt()) {
menuNum = input.nextInt();
}
return menuNum;
}
/*
* 系统提示窗口
*/
private static void printMenu() {
System.out.println("=====================================");
System.out.println("======欢迎登录学生信息查询系统=======");
System.out.println("=====================================");
System.out.println("请输入您要执行的操作》》》》》》》》》》》》》》》");
System.out.println("1:查询学生信息");
System.out.println("2:退出当前系统");
}
/*
* 对学生数组对象初始化
*/
private static void init() {
// 对stu数组初始化
for (int i = 0; i < stus.length; i++) {
int id = (int) (Math.random() * 90 + 10);
String name = "liuhang" + (int) (Math.random() * 3);
int score = (int) (Math.random() * 74 + 77);
String school = "家里蹲大学" + (int) (Math.random() * 100 + 1);
Student stu = new Student(id, name, score, school);
stus[i] = stu;
}
}
}
异常
声明是异常
**
* 根据用户输入 计算两个数相除
*
* 什么是异常?
* 不正常就是异常
*
* java.util.InputMismatchException 输入类型不匹配异常 程序运行时 报异常问题
*
* 1:jvm会处理程序中未处理的异常:
* a:暂停程序
* b:报错(异常内容【什么异常 原因描述】 异常行数 )
* 2:不要让jvm去处理异常
*
* @author wawjy
*
*/
public class Test01 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数》》》》");
int num1 = input.nextInt();
System.out.println("请输入第二个数》》》》");
int num2 = input.nextInt();
int result = num1/num2;
System.out.println(num1+"/"+num2+"="+result);
}
}
解决异常的办法
/**
* 处理异常 通过大量的if判定来确保程序没有异常,但是用户是万恶之源, 永远无法知晓他到底会做什么。
* 编写的判定逻辑不可能将所有情况都囊括进去,程序在执行过程中如果出现问题,出现异常 此时由于没有异常处理方案,导致交由jvm处理,jvm处理方式就是
* 暂停程序 报错。-》不能忍受的。
*
* 通过if判定完成异常校验: 代码臃肿、不利于阅读以及维护
*
* java提供了完整的异常处理方案,可以帮助我们在编写代码过程中,处理程序中的异常信息。
*
* try catch finally throws throw
*
*
* @author wawjy
*
*/
public class Test02 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数:》》》》");
if (input.hasNextInt()) {
int num1 = input.nextInt();
System.out.println("请输入第二个数:》》》》");
if (input.hasNextInt()) {
int num2 = input.nextInt();
if (num2 != 0) {
int result = num1 / num2;
System.out.println(num1 + "/" + num2 + "=" + result);
} else {
System.out.println("您输入除数为0 》》》");
}
} else {
System.out.println("您输入的数据有误》》》");
}
} else {
System.out.println("您输入的数据有误》》》");
}
}
}
try-catch
try-catch
/*
* try-catch:
* java中的异常机制:
* 语法结构:
* try{
* //有可能出现异常的代码块
* }catch(声明异常){
* 异常解决办法
* }
* 执行顺序:
* 1:执行try块中的内容
* 2:如果try块中内容出现异常,执行catch块
* 3:匹配catch中声明的异常信息 ,如果匹配上,则执行catch中的代码
* 4:继续执行后续代码
* 5:如果catch中的异常信息没有匹配到 那么此时交由jvm处理该异常
* catch:
* 中的类型一定要注意 要能够捕获到try快中实际出现的异常信息 如果忘记了具体的异常信息可以通过使用
* Exception去捕获异常信息
*
* 不要再catch块中做业务逻辑判定
*
*/
public class Test03 {
public static void main(String[] args) {
try {
System.out.println(1/0);//new ArithmeticException;出异常ArithmeticException
}catch(Exception e) {//Exception e = new ArithemeticException();
//记录异常信息
System.out.println("输入数据有误");
//错误信息记录下来
}
System.out.println("我是try-catch外的代码");
try {
//执行代码 可能出现的异常代码
}catch(InputMismatchException e) {
//具体的处理逻辑
}
}
}
try-多重catch
/**
* 语法结构: try{ //可能出现异常的代码段
}catch(异常1){ //异常 的解决办法
}catch(异常2){ //异常 的解决办法
* }.......{
} try多层catch执行顺序:
1:执行try块 如果出现异常 new出当前异常对象
2:逐一匹配catch中的异常内容
3:如果匹配上 执行对应的catch中的代码 整个try-catch执行结束 4:如果匹配上 jvm去解决当前异常信息 注意事项:
* 1:在多重catch中一般情况下会在最后一个catch语句中编写exception 用来捕获可能未被识别的异常信息
* 2:不要再第一个catch中编写父类异常 屏蔽所有子类异常
*
* 异常对象的常见方法: toString: 当前异常类型以及原因描述 printStackTrace: 打印堆栈信息 异常类型以及原因描述 异常位置
* getMessage:异常原因
*
* @author wawjy
*
*/
public class Test04 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数》》》》》");
try {
int num1 = input.nextInt();// InputMismatch
System.out.println("请输入第二个数》》》》》");
int num2 = input.nextInt();
int result = num1 / num2;
System.out.println(num1 + "/" + num2 + "=" + result);
} catch (ArithmeticException e) {
System.out.println("除数不能为0");
// System.out.println(e.toString());
// e.printStackTrace();
System.out.println(e.getMessage());
} catch (InputMismatchException e) {
System.out.println("用户输入有误");
} catch (Exception e) {
System.out.println("网络加载问题。。。。");
}
System.out.println("后续代码。。。");
}
}
try-catch-finally
/**
*
* try-catch-finally
*
* 语法结构: try{ //可能出现异常的代码 }catch(异常1){ //处理办法 }.....{
*
* }finally{ //代码块 关闭资源的代码 }
*
* @author wawjy
*
*/
public class Test05 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数》》》");
try {
int num1 = input.nextInt();
System.out.println("请输入第二个数》》》》");
int num2 = input.nextInt();
int result = num1/num2;
System.out.println(result);
input.close();
}catch(InputMismatchException e) {
System.out.println("输入有误");
}catch(ArithmeticException e) {
System.out.println("除数不能为0");
}catch(Exception e) {//Exception e = new IllegalStateException
System.out.println("网络加载有误");
}finally {
//一定会被执行
System.out.println("我是finally块中的代码");
}
System.out.println("我是后续代码");
}
}
jdk1.7 try-resourse
/**
*
* jdk1.7之后对于try-catch-finally的改变
* 可以通过对于流、网络连接对象的创建声明在try的()中,后续无需通过使用finally显式的关闭资源
* try(资源1;资源2.。。。){
* //可能出现的异常信息
* }catch(异常1){
* //解决办法
* }。。。。。{
*
* }
* @author wawjy
*
*/
public class Test07 {
public static void main(String[] args) {
try (Scanner input = new Scanner(System.in);){
System.out.println("请输入第一个数》》》》》");
int num1 = input.nextInt();
System.out.println("请输入第二个数》》》》》");
//input.close();
int num2 = input.nextInt();//new IllegalStateException
int result = num1/num2;
System.out.println(num1+"/"+num2+"="+result);
input.close();
}catch(InputMismatchException e) {
System.out.println("输入有误");
}catch(ArithmeticException e) {
System.out.println("除数不能为0");
}catch(Exception e) {//Exception e = new IllegalStateException
System.out.println("网络加载有误。。");
}
System.out.println("后续代码。。。。");
}
}
finally的执行位置
/**
* 测试如何让finally不执行
*
* retrun 语句不会让finally不执行
* finally先于return语句执行
* 代码中存在System.exit() 可以让finally不执行 但是一般不这么干
*
* 执行顺序:
* 1:执行try块 如果出现异常 new出当前异常对象
* 2:逐一匹配catch中的异常内容
* 3:如果匹配上, 执行对应的catch中的代码
* 4:如果未匹配上 ,jvm去解决当前异常信息
* 5:不论是否匹配成功 都会执行finally中内容
* finally中一般情况下编写关闭资源的操作
*
* @author wawjy
*
*/
public class Test06 {
public static void main(String[] args) {
System.out.println();
}
public static int test(){
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个数》》》》》");
try {
int num1 = input.nextInt();
System.out.println("请输入第二个数》》》》》");
int num2 = input.nextInt();////new IllegalStateException
int result = num1/num2;
System.out.println(num1+"/"+num2+"="+result);
System.exit(0);
return 1;
}catch(InputMismatchException e) {
System.out.println("输入有误");
}catch(ArithmeticException e) {
System.out.println("除数不能为0");
}catch(Exception e) {
System.out.println("网络加载有误。。");
}finally {
System.out.println("我是finally");
input.close();
}
return 2;
}
}
异常分类
异常继承关系.png
public class Test08 {
public static void main(String[] args) {
String str = null;
// System.out.println(str.length());
try {
InputStream is = new FileInputStream(new File(""));
} catch (FileNotFoundException e) {
System.out.println("路径有问题");
}
}
}
throw-throws
/*
*
* 异常机制:
* throws throw
* 1:throw 声明当前代码块中可能存在的异常信息 并且将当前异常信息抛出给调用者。
* 对于调用者而言 通过try-catch捕获异常
* 不管当前异常交由jvm解决
* 2:throw会导致当前程序中断掉 后续代码不执行
*
* throws 在方法外对外抛出某个异常,调用者解决当前异常。main方法中对外抛出的异常全部都交由jvm做。
*
* throws抛出异常 是异常解决的一种办法定义在方法的外部 形式参数后 可以抛出多个异常通过","分割
* throw 定义在方法内部,声明当前方法可能出现的异常信息 可以导致当前程序中断。
* 一般会将throws和throw在一起使用,throw 声明的异常是检查时异常需要和throws一起使用
* 但是throws可以单独使用
*
*/
public class Test09 {
public static void main(String[] args) throws FileNotFoundException {
Student stu1 = new Student();
stu1.setName("张三");
try {
stu1.setAge(-1);
}catch(RuntimeException e) {
System.out.println("参数错误");
}
System.out.println(stu1);
}
}
自定义异常
image
/*
* 自定义异常:
* 1:jdk中提供的异常信息不满足目前的使用
* 2:如何自定义异常:
* a:声明一个自定义异常类
* b:继承Exception
* c:编写两个构造器 一个空 一个带字符串的构造器
*
* 使用自定义异常:
*
*/
代码:
public class AgeException extends Exception{
public AgeException() {
}
//当前异常描述原因
public AgeException(String message) {
super(message);
}
}
public class Test10 {
public static void main(String[] args) {
User u = new User();
try {
u.setAge(-1);
}catch(AgeException e) {
System.out.println(e.getMessage());
}
System.out.println(u);
}
}
class User{
@Override
public String toString() {
return "User [age=" + age + "]";
}
private int age;
public User() {
super();
// TODO Auto-generated constructor stub
}
public int getAge() {
return age;
}
public void setAge(int age) throws AgeException{
if(age<0||age>100) {
throw new AgeException("年龄输入有误");
}
this.age = age;
}
}