• Java学习笔记(11)


    自定义异常类:

    自定义异常类的步骤:自定义一个类继承Exception即可

    public class CustomClass {
    
        public static void main(String[] args) throws NoIpException{
            // TODO Auto-generated method stub
            String ip=null;
            feiQ(ip);
        }
        public static void feiQ(String ip) throws NoIpException{
            if (ip==null) {
                //抛出一个没有网线的异常
                throw new NoIpException("没有插网线啊");
            }
            System.out.println("正常显示好友列表!");
        }
    }
    class NoIpException extends Exception{
        public NoIpException() {}
        public NoIpException(String message) {
            super(message); //调用了Exception一个参数的构造函数
        }
    }
    
    结果:
    Exception in thread "main" test.NoIpException: 没有插网线啊    //这里会出现这样的结果是因为我们把上面的异常抛给了feiQ的调用者main函数,也就是jvm,它会默认打印异常的栈信息的,所以会出现下面的东西
        at test.CustomClass.feiQ(CustomClass.java:13)
        at test.CustomClass.main(CustomClass.java:8)

    还可以用try-catch方法:

    public class CustomClass {
    
        public static void main(String[] args) /*throws NoIpException*/{
            // TODO Auto-generated method stub
            String ip=null;
            try {
                feiQ(ip);
            }catch(NoIpException e) {
                e.printStackTrace();
                System.out.println("马上插上网线!");
            }
        }
        public static void feiQ(String ip) throws NoIpException{
            if (ip==null) {
                //抛出一个没有网线的异常
                throw new NoIpException("没有插网线啊");
            }
            System.out.println("正常显示好友列表!");
        }
    }
    class NoIpException extends Exception{
        public NoIpException() {}
        public NoIpException(String message) {
            super(message); //调用了Exception一个参数的构造函数
        }
    }
    
    结果:
    test.NoIpException: 没有插网线啊
        at test.CustomClass.feiQ(CustomClass.java:18)
        at test.CustomClass.main(CustomClass.java:9)
    马上插上网线!

     例题:定义一个没钱的异常    ,如果带够了钱,那么就可以吃上木桶饭,如果没有,那么就会抛出一个没钱的异常。

    public class CustomClassTest {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int money=6;
            try {
                eat(money);
            }catch(NoMoneyException e) {
                e.printStackTrace();
                System.out.println("跟我洗碗一个月!");
            }
        }
        public static void eat(int money) throws NoMoneyException{
            if (money<10) {
                //抛出一个没有钱的异常
                throw new NoMoneyException("吃霸王餐!");
            }
            System.out.println("吃上了香喷喷的木桶饭!");
        }
    }
    //定义一个没钱的异常
    class NoMoneyException extends Exception{
        public NoMoneyException() {}
        public NoMoneyException (String message) {
            super(message);
        }
    }
    
    结果:
    test.NoMoneyException: 吃霸王餐!
        at test.CustomClassTest.eat(CustomClassTest.java:18)
        at test.CustomClassTest.main(CustomClassTest.java:9)
    跟我洗碗一个月!

    异常分为:

        运行时异常:如果一个方法内部抛出了一个运行时异常,那么方法上可以声明也可以不声明,调用者可以处理也可以不处理

        编译时异常(非运行时异常,受检异常) :如果一个方法内部抛出了一个编译时异常对象,那么方法上就必须要声明,而且调用者也必须要处理。

    运行时异常:RuntimeException以及RuntimeException子类都是属于运行时异常

    编译时异常:除了运行时异常就是编译时异常。

    疑问:为什么java编译器会如此严格要求编译时异常,对运行时异常如此宽松?

        运行时异常都是可以通过程序员良好的编程习惯去避免的,所以java编译器就没有严格要求处理运行时异常

        而编译时异常是不能通过代码来避免的,所以就必须要求程序员来处理

    资源文件一旦使用完毕,一定要释放资源文件,否则其他的程序无法对这个资源文件进行操作。

    finally块:

    finally块的使用前提是必须要存在try块才能使用

    public class Finally {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            div(4,0);
        }
        public static void div(int a,int b) {
            try {
                int c=a/b;
                System.out.println("c="+c);
            }catch(Exception e) {
                System.out.println("出现了除数为0的异常");
                //throw e;
            }finally {
                System.out.println("finally的代码被执行了");
            }
        }
    }
    
    结果:
    出现了除数为0的异常
    finally的代码被执行了

    finally块的代码在任何情况下都会执行的,除了jvm退出的情况(System.exit)

    finally非常适合做资源释放的工作,这样子可以保证资源文件在任何情况下都会被释放。

    try块的三种组合方式:

    1.比较适用于有异常要处理,但是没有资源要释放的。

        try{

        可能发生异常的代码

        }catch(捕获的异常类型  变量名){

        处理异常的代码

        }

    2.比较适用于既有异常要处理,又要释放资源的代码

        try{

        可能发生异常的代码

        }catch(捕获的异常类型  变量名){

        处理异常的代码

        }finally{

        释放资源的代码;

        }

    3.比较适用于内部抛出的是运行时异常,并且有资源要被释放。 (合法但不常用)

        try{

        可能发生异常的代码

        }finally{

        释放资源的代码;

        }

    包:

    包的好处:

    1. 解决类名重复产生冲突的问题
    2. 便于软件版本的发布

    定义包的格式:package   包名;

    包名命名规范:包名全部小写

    包语句要注意的事项:

    1. package语句必须位于java文件中的第一个语句
    2. 如果一个类加上了包语句,那么该类的完整类名就是 : 包名.类名
    3. 一个java文件只能有一个包语句  

    在dos命令中,  “.“ 表示当前的路径

    java  -d   指定类文件的存放路径     java源文件

    有了包之后类与类之间的访问:(默认情况是每个类都是一个包)

    导包语句作用:简化书写(误区:把一个类导入到内存中)

    导包语句的格式:

        import  包名.类名;  (导入xxx包中的某个类)

    导包语句要注意的细节:

    1. 一个java文件中可以出现多句导包语句
    2. "*"星号是导包语句的通配符。可以匹配任何的类名   (星号只能用作匹配类名,不能用作匹配包名)
    3. import  包名.*   是不会作用于此包下面的子包的

    推荐使用  import  包名.类名    而不要使用  import 包名.*     因为使用*通配符会导致结构不清晰

    什么时候使用import语句:

    1. 相互访问的两个类b不是在同一个包下面,这时候就需要使用到导包语句
    2. java.lang包是默认导入的,不需要我们自己导入

    权限修饰符:权限修饰符就是控制被修饰的成员的范围可见性。

      public(公共) protected(受保护) default(缺省,也就是没有写东西) private(私有)(大到小)
    同一个类 true true true true
    同一个包 true true true false
    子父类 true true false false
    不同包 true false false false

    注意:在不同包下面只有public与protected可以访问,而且protected必须是在继承关系下才能够访问。

    打jar包:需要使用到jdk的开发工具(jar.exe)

    jar的用法:   jar   cvf (-cvf)    jar文件的名字    class文件或者是文件夹

    打jar包要注意的事项:

    1. 一个程序打完了jar之后,必须要在清单文件上指定入口类:格式  Main-Class: (注意这里有一个空格)包名.类名
    2. jar包双击运行仅对于图形化界面的程序起作用,对控制台的程序不起作用

     jar文件的作用:

    1. 方便用户快速运行一个项目
    2. 提供工具类以jar包的形式给别人使用

    如果使用jar包里面的类必须要先设置classpath路径

    import javax.swing.*;
    public class Test {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            JFrame frame=new JFrame("QQ程序");
            frame.setSize(400, 500);
            frame.setVisible(true);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    }
    
    结果为一个界面

    模板模式:

    某类事情的步骤有些是固定的,有些是会发生变化的,那么这时候我们可以为这类事情提供一个模板代码,从而提高效率。

    模板模式的步骤:

    1. 先写出解决该类事情其中一件的解决方案
    2. 分析代码,把会发生变化的的代码抽取出来独立成一个方法,把该方法也描述成一个抽象的方法
    3. 使用final修饰模板方法,防止别人重写你的模板方法
    public class RunTime extends MyRunTime{
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            //MyRunTime time=new MyRunTime();
            //time.getTime();
            RunTime r=new RunTime();
            r.getTime();
        }
        public void code() {
            for (int i=0;i<100;i++) {
                System.out.println("i="+i);
            }
        }
    }
    abstract class MyRunTime{
        public MyRunTime() {}
        public final void getTime() {
            long startTime=System.currentTimeMillis(); //记录开始的时间
            code();
            long endTime=System.currentTimeMillis();  //记录结束时间
            System.out.println("运行时间是:"+(endTime-startTime));
        }
        public abstract void code();
    }
    
    结果:
    i=0
    i=1
    i=2
    i=...
    i=99
    运行时间是:13

    清除重复元素:

    例,清除{11,2,4,2,10,11}中的重复元素,并且打印出来,要求不允许又多余的空间

    import java.util.*;
    public class ClearRepeat {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int[] arr= {11,2,4,2,10,11};
            arr=clearRepeat(arr);
            System.out.println("清除重复元素的数组:"+Arrays.toString(arr));
        }
        public static int[] clearRepeat(int[] arr) {
            //先计算出重复元素的格式
            int count=0;   //记录重复元素的个数
            for (int i=0;i<arr.length-1;i++) {
                for (int j=i+1;j<arr.length;j++) {
                    if (arr[i]==arr[j]) {
                        count++;
                        break;
                    }
                }
            }
            System.out.println("重复元素的个数:"+count);
            
            //新数组的长度
            int newLength=arr.length-count;
            //创建一个新的数组
            int[] newArr=new int[newLength];
            int index=0;//定义一个变量记录新数组使用的索引值
            //把旧数组的元素存储到新数组中,存入新数组之前要先判断该元素是否存在新数组中,如果存在了,那么该元素就不要了
            for (int i=0;i<arr.length;i++) {
                int temp=arr[i];  //取出旧数组的元素
                boolean flag=false;//定义一个变量用于记录当前元素是否为重复元素,默认不是重复元素
                //检查新数组是否存在取出的元素
                for (int j=0;j<newArr.length;j++) {
                    if (newArr[j]==temp) {
                        flag=true;
                        //该元素已经存在了新数组中
                        break;
                    }
                }
                //不是重复元素
                if (flag==false) {
                    newArr[index++]=temp;
                }
            }
            return newArr;
        }
    }
    
    结果:
    重复元素的个数:2
    清除重复元素的数组:[11, 2, 4, 10]
  • 相关阅读:
    【KMP】Period
    【KMP】Cyclic Nacklace
    【KMP】Oulipo
    【KMP】Number Sequence
    二分
    Stock 贪心经典 Zoj2921
    D. Block Tower
    烦人的dp
    搜索
    hdu 一个人的旅行
  • 原文地址:https://www.cnblogs.com/zhangwugai/p/10337605.html
Copyright © 2020-2023  润新知