黑马程序员技术交流社区

标题: 【石家庄校区】易错点整理 [打印本页]

作者: WangQiJourney    时间: 2019-2-21 15:19
标题: 【石家庄校区】易错点整理

异常一
  创建人
  
  王琦
  
  问题标题
  
  运行异常
  
  问题分类
  
  抛出异常的过程
  
  一级话题
  
  循环输入中,发生一次异常后,之后的循环从一开始直接异常,而不会执行try里的语句。
  
  运行结果:(输入)1a
             格式错误
             格式错误
             格式错误
             ……
  
  问题补充
  
  
  
  附件
  
  
public  static void main(String[] args) {
     Scanner sc = new Scanner(System.in);
     int a = 0;           
     while(true)
     try{
        a = sc.nextInt();  //若用户输入格式不正确,会抛InputMismatchException
        break;
     }catch (Exception e){
        System.out.println("格式错误");
     }
  }
  
  
  问题答案
  
  问题分析:
  发生异常的是Scanner的对象sc调用的方法nextInt(),而不是变量a。
  故而再次执行循环体的a =  sc.nextInt();时没有重置sc对象,这是还是异常状态,直接报错。
  
  问题解决方法:
  在catch下的代码里重置Scanner对象sc
      }catch (Exception e){
        System.out.println("格式错误");
  

Sc = new Scanner(System.in);
     }

  
异常二
  创建人
  
  王琦
  
  问题标题
  
  编译问题
  
  问题分类
  
  编译错误
  
  一级话题
  
  Error:(25, 27) java: 在相应的 try 语句主体中不能抛出异常错误access01.day05.test.test5_hard.ScanError
  
  问题补充
  
  自定义了异常类ScanError
  
  附件
  
  age = scanner.next();
  char[] ageArray = age.toCharArray();
  try {
     for (int i = 0; i <  ageArray.length; i++) {
        if (ageArray < '0' || ageArray  > '9') {
           isRight = false;           
        }
        isRight = true;
     }
  } catch (ScanError e) {               //这里是25行
     System.out.println("您输入的年龄格式有误,请重新输入!");
  }
  
  
  问题答案
  
  问题分析:
  使用try…catch语句处理可能发生异常的语句,
  对于JDK中已经定义好的异常类,只要在方法声明处throws就可以了,运行时发生异常就会被catch捕获到
  对于自定义异常,使用try…catch,try代码里要throw 自定义的异常对象,才能被catch捕获到
  
  问题解决方法:
  在if判断语句的执行体内最后一行添加
  throw  new ScanError();            
  
异常三
  创建人
  
  王琦
  
  问题标题
  
  运行异常
  
  问题分类
  
  Object类中的wait()方法和notify()方法
  
  一级话题
  
  Exception in thread "Thread-0"  java.lang.IllegalMonitorStateException
          at  java.base/java.lang.Object.wait(Native Method)
          at  java.base/java.lang.Object.wait(Object.java:516)
          at  access01.day06.practice.BaoZiPu.GuKe.run(GuKe.java:17)
          at  java.base/java.lang.Thread.run(Thread.java:844)              
  
  
  问题补充
  
  
  
  附件
  
  //这是其中一个Runnable实现类,用于建立新的线程;
  //另外还有其他的Runnable实现类,也有wait()和notify()方法
  synchronized (bz){
     if(bz.isFlag()==true){
        try {
           wait();
        } catch (InterruptedException e)  {
           e.printStackTrace();
        }
     }
     ……
     notify();         //用于唤醒其他线程的wait()
  }
  
  问题答案
  
  问题分析:
  作为Object类的方法,wait()和notify()要使用对象来调用,注意直接写wait()和notify()编译是不报错的。
  
  问题解决方法:
  把wait()和notify()改为bz.wait();和bz.notify();
  
异常四
  创建人
  
  王琦
  
  问题标题
  
  编译问题
  
  问题分类
  
  Lambda表达式的使用前提
  
  一级话题
  
  Error:(14, 17) java: 此处不应为 lambda 表达式
  
  问题补充
  
  
  
  附件
  
  //在这之外建立一个接口,名为LambdaInterface,
  //这里为main方法中,
  //要以常规匿名内部类和λ表达式两种方式创建对象并调用重写的eat方法
  new LambdaInterface() {
     @Override
     public void eat() {
        System.out.println("吃饭");
     }
  }.eat();                            //以上为方式一,常规方式,无异常
  
  ()-> {
     System.out.println("吃饭");
  }.eat();                            //以上为方式二,λ表达式,出现异常
  
  
  
  问题答案
  
  问题分析:
  这里没有上下文,没有指定λ表达式用的哪个接口,无法推导出,不能使用。
  也就是λ表达式使用前提2:当一个方法需要传递这个符合条件的接口的实现类对象时才可以使用,这时候方法中指定了需要哪个接口,可以推导出来,就可以使用λ表达式。
  
  
  问题解决方法:
  定义一个多态对象来接收这个表达式(λ表达式本质就是个对象),然后再调用方法。
  LambdaInterface  lambdaInterface = ()->{
     System.out.println("
吃饭");
  };
  lambdaInterface.eat();

  
  或是再main方法外定义一个静态方法,方法参数列表为这个接口的多态对象,并在方法内调用这个对象的方法。
  然后再main方法内调用这个静态方法,把λ表达式作为参数传递进去。
  





异常五
  创建人
  
  王琦
  
  问题标题
  
  功能实现错误
  
  问题分类
  
  \r、\n在输入输出流中的应用
  
  一级话题
  
  通过输出流建立文件并写入数据,
  而后通过输入流读取这个文件并将数据打印输出:
  执行代码后,生成的文件a.txt中为:
  a
  b
  c
  而控制台输出却为:
  a
  c
  
  问题补充
  
  
  
  附件
  
  
  
FileOutputStream  fos = newFileOutputStream("itheima\\src\\ day09\\a.txt");
  
fos.write(97);
  fos.write('\n');
  fos.write('b');
  fos.write('\r');
  fos.write('c');
  
fos.close();
  
  FileInputStream fis = new FileInputStream("itheima\\src\\  day09\\a.txt");
  int b;
  while ((b = fis.read()) != -1) {
     System.out.print((char) b);
  
}
  fis.close();
  
  
  
  问题答案
  
  问题分析:
  在Windows中:
  '\r' 回车,回到当前行的行首,而不会换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖;
  '\n' 换行,换到当前位置的下一行,而且不一定是下一行的行首;
  \r\n才是回车加换行,但它不是字符,只能应用在字符串中。
  
  本题中,
  文件里的\r是可以被读取出来的,但使用sout打印输出时会作为回车输出,也就是回到行首,再输出后面的就覆盖了文字。
  
  
  
  问题解决方法:
  将整段write方法的调用修改为:
  fos.write("a\r\nb\r\nc".getBytes());
  
  






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2