小白学习Java开发的第十二天

以下内容为之前的补充以及后续的扩展

静态内部类完成单例

/*** 编写静态内部类完成单例模式创建 
* 线程安全问题: 天然线程安全 
* 延迟加载: 能做到延迟加载 
* 类何时被加载: 调用静态内容 创建对象 
* 类加载的时候 首先将静态内容加载大内存中 
* @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;
    }
    
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。