黑马程序员技术交流社区
标题:
把StringBufilder定义在函数里面和外面的区别
[打印本页]
作者:
张吉日
时间:
2012-9-6 21:26
标题:
把StringBufilder定义在函数里面和外面的区别
本帖最后由 张吉日 于 2012-9-7 14:37 编辑
/*StringBuilder sb = new StringBuilder(); //此代码在16行处
为什么我把他定义在 public String myReadLine()throws IOException 方法外就会无限循环..
放在外面不也是调用的吗?????有什么不同之处
*/
import java.io.*;
class MyBufferedReader extends Reader
{
private Reader r;
MyBufferedReader(Reader r)
{
this.r=r;
}
public String myReadLine()throws IOException
{
StringBuilder sb = new StringBuilder();
int line = 0;
while ((line=r.read())!=-1)
{
if(line=='\r')
continue;
if(line=='\n')
return sb.toString();//一次次循环 当结尾到\n的时候返回.
else
sb.append((char)line);//添加元素.你的任务就是添加元素,停止的事交给return
}
if(sb.length()!=0)
return sb.toString();
return null;
}
public void close()throws IOException
{
r.close();
}
public int read(char[] cbuf, int off, int len)throws IOException
{
return read(cbuf,off,len);
}
}
class 装饰法
{
public static void main(String[] args)
{
FileReader fr = null;
MyBufferedReader mybufr = null;
try
{
fr = new FileReader("FileStream.java");
mybufr = new MyBufferedReader(fr);
String str = null;
while ((str=mybufr.myReadLine())!=null)
{
System.out.println(str);
}
}
catch (IOException e)
{
throw new RuntimeException("失败");
}
finally
{
try
{
if(mybufr!=null)
mybufr.close();
}
catch (IOException e)
{
throw new RuntimeException("读取失败");
}
}
}
}
复制代码
作者:
杨卓儒
时间:
2012-9-6 21:44
把无限循环的代码贴上来 看看
作者:
杨震
时间:
2012-9-6 22:06
你意思是将sb作为对象的一个数据域吧,那样的话你读的数据不都存在sb里面了吗,sb装的是你所读的所有数据,不可能为空的(除非文件为空),所以MyReadLine()方法不会返回空,main里面的while也就不会结束;
但你将sb定义在MyReadLine里面,每天调用此函数,sb都为空,如果最后一次调用没有数据了,sb就为空,就是返回null,while就会结束
作者:
佟亚鹏
时间:
2012-9-7 13:35
呵呵,你的这个错误挺有意思的,StringBuilder sb = new StringBuilder();,这句代码放在方法里面是临时变量,每一次方法执行时都会new出一个新的对象,而放在外面是成员变量,new出来以后sb一直用的都是同一个对象,这两种方式有什么的不同呢?
当 StringBuilder sb = new StringBuilder() 放在你的方法 myReadLine外面作为成员变量时,当第一次执行这个方法时sb的长度已经不为空了,也就是长度不为0的情况(除非你的文件是空文件)。
注意你的 myReadLine 方法里这段代码
if (sb.length() != 0)
return sb.toString();
复制代码
所以不管文件是否读完,上面这段代码都会被执行,把sb.toString()的内容返回回去,在看看main方法里你的代码
String str = null;
while ((str = mybufr.myReadLine()) != null) {
System.out.println(str);
}
复制代码
mybufr.myReadLine()
返回的不为空,就是str不为空,所以这个条件永远都成立。。。。。。可怕的死循环到来了
作者:
佟亚鹏
时间:
2012-9-7 13:39
呵呵,你的这个错误挺有意思的,StringBuilder sb = new StringBuilder();,这句代码放在方法里面是临时变量,每一次方法执行时都会new出一个新的对象,而放在外面是成员变量,new出来以后sb一直用的都是同一个对象,这两种方式有什么的不同呢?
当 StringBuilder sb = new StringBuilder() 放在你的方法 myReadLine外面作为成员
作者:
佟亚鹏
时间:
2012-9-7 13:39
呵呵,你的这个错误挺有意思的,StringBuilder sb = new StringBuilder();,这句代码放在方法里面是临时变量,每一次方法执行时都会new出一个新的对象,而放在外面是成员变量,new出来以后sb一直用的都是同一个对象,这两种方式有什么的不同呢?
当 StringBuilder sb = new StringBuilder() 放在你的方法 myReadLine外面作为成员变量时,当第一次执行这个方法时sb的长度已经不为空了,也就是长度不为0的情况(除非你的文件是空文件)。
注意你的 myReadLine 方法里这段代码
if (sb.length() != 0)
return sb.toString();
复制代码
所以不管文件是否读完,上面这段代码都会被执行,把sb.toString()的内容返回回去,在看看main方法里你的代码
String str = null;
while ((str = mybufr.myReadLine()) != null) {
System.out.println(str);
}
复制代码
mybufr.myReadLine()
返回的不为空,就是str不为空,所以这个条件永远都成立。。。。。。可怕的死循环到来了
作者:
佟亚鹏
时间:
2012-9-7 13:45
呵呵,网速太卡了,点击了好几次,唉。。。。。。
作者:
AngieFans85
时间:
2012-9-7 14:09
sb.delete(0, sb.length());
把以上的一句代码放在你的myReadLine()方法的首行就可以了,可以保证每次调用myReadLine()时,StringBuilder都没有内容,当你FileStream.java文件的内容已经读到末尾时,你若循环调用你的myReadLine()方法,就循环执行以下代码:
if (line == '\n')
return sb.toString();
复制代码
而你的StringBuilder的内容一直为空,所以最后一次myReadLine()方法的时候,就肯定返回null了,就不会再死循环了.
作者:
张吉日
时间:
2012-9-7 14:35
谢谢各位 明白了
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2