黑马程序员技术交流社区

标题: 自定义BufferedReader时出现的空指针异常 [打印本页]

作者: 吴扬    时间: 2012-7-13 21:55
标题: 自定义BufferedReader时出现的空指针异常
本帖最后由 吴扬 于 2012-7-16 15:19 编辑

今天根据视频练习自定义BufferedReader类的时候出现了一个空指针异常,烦请大家帮忙看下
自定义BufferedReader类:
  1. public class MyBufferedReader extends Reader{     //这里继承了Reader类
  2.         private Reader reader;
  3.         public MyBufferedReader(Reader reader) {
  4.                 super(reader);               //调用了Reader类的构造方法     //解决办法:这里应该改为this.reader = reader;
  5.         }
  6.         
  7.         public String myReadLine() throws IOException
  8.         {
  9.                 StringBuilder sb = new StringBuilder();
  10.                 int ch = 0;
  11.                 while((ch = reader.read()) != -1)
  12.                 {
  13.                         if(ch == '\r')
  14.                                 continue;
  15.                         if(ch == '\n')
  16.                                 return sb.toString();
  17.                         else
  18.                                 sb.append((char)ch);
  19.                 }
  20.                 if(sb.length() != 0)
  21.                 {
  22.                         return sb.toString();
  23.                 }
  24.                 return null;
  25.                
  26.         }
  27.         
  28.         public void close() throws IOException
  29.         {
  30.                 reader.close();
  31.         }

  32. @Override
  33. public int read(char[] arg0, int arg1, int arg2) throws IOException {
  34.   // TODO Auto-generated method stub
  35.   return 0;
  36. }
  37.         
  38. }
复制代码
测试类:
  1. public static void main(String[] args) throws IOException {
  2.                 // TODO Auto-generated method stub
  3.                 FileReader fr = new FileReader("d:\\abc.txt");
  4.                 MyBufferedReader myBufferedReader = new MyBufferedReader(fr);
  5.                
  6.                 String buffer = null;
  7.                
  8.                 while((buffer = myBufferedReader.myReadLine()) != null)   //这里会报空指针异常
  9.          {
  10.                         System.out.println(buffer);
  11.                 }
  12.                
  13.                 myBufferedReader.myClose();
  14.         }
复制代码
后面经过调试才发现异常产生的原因是继承了Reader类,调用了它的构造方法产生的,但是想了半天也没想明白为什么继承了BufferedReader类就会出现空指针异常,
麻烦各位可以帮我看下吗?谢谢...



作者: 全海波    时间: 2012-7-13 22:42
public static void main(String[] args) throws IOException {
                // TODO Auto-generated method stub
                  String buffer = null;//位置调一下

                FileReader fr = new FileReader("d:\\abc.txt");
                MyBufferedReader myBufferedReader = new MyBufferedReader(fr);
                //  String buffer = null;如果你在里定义的话,那buffer没有指向任何对象

                while((buffer = myBufferedReader.myReadLine()) != null)   //这里会报空指针异常
         {
                        System.out.println(buffer);
                }
               
                myBufferedReader.myClose();
        }
作者: 尹善波    时间: 2012-7-13 23:42
import java.io.*;
class MyBufferedReader
{     
        private Reader reader;
        public MyBufferedReader(Reader reader)
       {
                this.reader = reader;    //你原代码这里用的是中文的分号           
        }
        
        public String myReadLine() throws IOException
        {
                StringBuilder sb = new StringBuilder();
                int ch = 0;
                while((ch = reader.read()) != -1)
                {
                        if(ch == '\r')
                                continue;
                        if(ch == '\n')
                                return sb.toString();
                        else
                                sb.append((char)ch);
                }
                if(sb.length() != 0)
                {
                        return sb.toString();
                }
                return null;
               
        }
        
        public void myClose() throws IOException//你原代码中这里的方法名字写错了改过来就欧了
        {
                reader.close();
        }

       public int read(char[] arg0, int arg1, int arg2) throws IOException
      {
             return 0;
      }
}
class Test1
{
                 public static void main(String[] args) throws IOException
               {
                 FileReader fr = new FileReader("d:\\abc.txt");
                MyBufferedReader myBufferedReader = new MyBufferedReader(fr);
               
                String buffer = null;
               
                while((buffer = myBufferedReader.myReadLine()) != null)   
              {
                        System.out.println(buffer);
               }
               
                myBufferedReader.myClose();
             }        
}
我给你改了一下就可以了,其它地方没什么问题


作者: 陈云帆    时间: 2012-7-13 23:58
public MyBufferedReader(Reader reader)
       {
                this.reader = reader;        //必须有不然this.reader是没有赋值的,不能用

        }

作者: 刘煜    时间: 2012-7-14 01:31
java中的空指针异常java.lang.NullPointerException是最麻烦的,空指针异常产生的主要原因如下:
(1)当一个对象不存在时又调用其方法会产生异常obj.method() // obj对象不存在
(2)当访问或修改一个对象不存在的字段时会产生异常obj.method() // method方法不存在
空指针的解决办法:
重点关注报错发生的所在行,通过空指针异常产生的两条主要原因诊断具体的错误。同时为了避免空指针的发生,最好在做判断处理时将“null”或者空值放于设定的值之前。在这里给你举个例子:
    为了确保进行操作或引用的对象非空,假设我们要对某对象进行操作或引用,我们首先去检查该对象是否已经实例化且不为空;并且在系统中加入针对对象为空时情况的处理。如:采用String对象保存用户提交的结果;在如果涉及对象的操作时,先检测其是否为空后,检查到对象为空后,可再选择进行以下任一种处理方式:
  处理方式 1) 检查到对象为空时,设置对象值为空字符串或一个默认值;
  处理方式 2) 检测到对象为空时,根本不执行某操作,直接跳转到其他处理中。
  处理方式 3) 检查到对象为空时,提示用户操作有错误。
  将代码段2按以上方式进行改写,得到:
方式1:
  String userName = request.getParameter("username");
  // 该变量值为空时,转化为默认空字符串
  If (userName == null)
  userName = "";
  If (userName.equals("root"))
  {..........}
方式2:
  String userName = request.getParameter("username");
  // 该变量值为空时,转化为默认空字符串,不执行有关操作。
  If (usreName != null)
  {
  If (userName.equals("root"))
  {..........}
}
方式3:
  String userName = request.getParameter("username");
  // 该变量值为空时,转化为默认空字符串,不执行有关操作。
  If (usreName == null)
  {  // 提示用户输入信息为空
  }
实际中,上面提供到三种处理方式也同样适用于其他异常的处理:
异常处理方式 1) 检查到异常出现,设置对象值为空字符串或一个默认值;
异常处理方式 2) 检测到异常出现,根本不执行某操作,直接跳转到其他处理中。
异常处理方式 3) 检查到异常出现,提示用户操作有错误。
讲到这里表面感觉跟你的问题相差很远,实际上我觉得解决空指针异常的方法的思想和步骤是不变的。结合上边解决问题的方法或思想,针对你的代码,我们重点关注出现异常的所在行出现的对象,有Buffer和myBufferedReader,而Buffer可以确定已经赋值过了,有问题的只能是myBufferedReader的赋值,而与myBufferedReader赋值有关的就是与初始化有关系,与初始化有关系的就是构造函数。在这里你继承了Reader类,子类的构造函数中就会隐式的执行一句super(reader),执行了super(reader)就不会执行this.reader= reader(因为两句话都只能在构造函数第一行,要执行this.reader= reader必须手动加上),就不会对成员变量reader赋值,reader为空就出现了空指针异常。解决方法就是在构造函数加上this.reader= reader。。以后遇到其他的空指针异常就可以参考上边举得例子。
我自己的理解和分析,希望对你有帮助。

作者: 吴扬    时间: 2012-7-16 15:19
谢谢大家,问题已经找到了!




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