java及编程中常见问题.doc

上传人:大米 文档编号:559222141 上传时间:2022-11-23 格式:DOC 页数:117 大小:589.97KB
返回 下载 相关 举报
java及编程中常见问题.doc_第1页
第1页 / 共117页
java及编程中常见问题.doc_第2页
第2页 / 共117页
java及编程中常见问题.doc_第3页
第3页 / 共117页
java及编程中常见问题.doc_第4页
第4页 / 共117页
java及编程中常见问题.doc_第5页
第5页 / 共117页
点击查看更多>>
资源描述

《java及编程中常见问题.doc》由会员分享,可在线阅读,更多相关《java及编程中常见问题.doc(117页珍藏版)》请在金锄头文库上搜索。

1、每天在写Java程序,其实里面有一些细节大家可能没怎么注意,这不,有人总结了一个我们编程中常见的问题。虽然一般没有什么大问题,但是最好别这样做。另外这里提到的很多问题其实可以通过Findbugs( http:/ )来帮我们进行检查出来。字符串连接误用错误的写法:1 String s = ; 2 for (Person p : persons) 3 s += , + p.getName(); 4 5 s = s.substring(2); /remove first comma 正确的写法:6 StringBuilder sb = new StringBuilder(persons.size()

2、 * 16); / well estimated buffer 7 for (Person p : persons) 8 if (sb.length() 0) sb.append(, ); 9 sb.append(p.getName); 10 错误的使用StringBuffer错误的写法:11 StringBuffer sb = new StringBuffer(); 12 sb.append(Name: ); 13 sb.append(name + n); 14 sb.append(!); 15 . 16 String s = sb.toString(); 问题在第三行,append cha

3、r比String性能要好,另外就是初始化StringBuffer没有指定size,导致中间append时可能重新调整内部数组大小。如果是JDK1.5最好用StringBuilder取代StringBuffer,除非有线程安全的要求。还有一种方式就是可以直接连接字符串。缺点就是无法初始化时指定长度。正确的写法:17 StringBuilder sb = new StringBuilder(100); 18 sb.append(Name: ); 19 sb.append(name); 20 sb.append(n!); 21 String s = sb.toString(); 或者这样写:22 S

4、tring s = Name: + name + n!; 测试字符串相等性错误的写法:23 if (pareTo(John) = 0) . 24 if (name = John) . 25 if (name.equals(John) . 26 if (.equals(name) . 上面的代码没有错,但是不够好。compareTo不够简洁,=原义是比较两个对象是否一样。另外比较字符是否为空,最好判断它的长度。正确的写法:27 if (John.equals(name) . 28 if (name.length() = 0) . 29 if (name.isEmpty() . 数字转换成字符串错

5、误的写法:30 + set.size() 31 new Integer(set.size().toString() 正确的写法:32 String.valueOf(set.size() 利用不可变对象(Immutable)错误的写法:33 zero = new Integer(0); 34 return Boolean.valueOf(true); 正确的写法:35 zero = Integer.valueOf(0); 36 return Boolean.TRUE; 请使用XML解析器错误的写法:37 int start = xml.indexOf() + .length(); 38 int

6、end = xml.indexOf(); 39 String name = xml.substring(start, end); 正确的写法:40 SAXBuilder builder = new SAXBuilder(false); 41 Document doc = doc = builder.build(new StringReader(xml); 42 String name = doc.getRootElement().getChild(name).getText(); 请使用JDom组装XML错误的写法:43 String name = . 44 String attribute

7、= . 45 String xml = 46 + name + 47 +; 正确的写法:48 Element root = new Element(root); 49 root.setAttribute(att, attribute); 50 root.setText(name); 51 Document doc = new Documet(); 52 doc.setRootElement(root); 53 XmlOutputter out = new XmlOutputter(Format.getPrettyFormat(); 54 String xml = out.outputStrin

8、g(root); XML编码陷阱错误的写法:55 String xml = FileUtils.readTextFile(my.xml); 因为xml的编码在文件中指定的,而在读文件的时候必须指定编码。另外一个问题不能一次就将一个xml文件用String保存,这样对内存会造成不必要的浪费,正确的做法用InputStream来边读取边处理。为了解决编码的问题, 最好使用XML解析器来处理。未指定字符编码错误的写法:56 Reader r = new FileReader(file); 57 Writer w = new FileWriter(file); 58 Reader r = new In

9、putStreamReader(inputStream); 59 Writer w = new OutputStreamWriter(outputStream); 60 String s = new String(byteArray); / byteArray is a byte 61 byte a = string.getBytes(); 这样的代码主要不具有跨平台可移植性。因为不同的平台可能使用的是不同的默认字符编码。正确的写法:62 Reader r = new InputStreamReader(new FileInputStream(file), ISO-8859-1); 63 Wr

10、iter w = new OutputStreamWriter(new FileOutputStream(file), ISO-8859-1); 64 Reader r = new InputStreamReader(inputStream, UTF-8); 65 Writer w = new OutputStreamWriter(outputStream, UTF-8); 66 String s = new String(byteArray, ASCII); 67 byte a = string.getBytes(ASCII); 未对数据流进行缓存错误的写法:68 InputStream i

11、n = new FileInputStream(file); 69 int b; 70 while (b = in.read() != -1) 71 . 72 上面的代码是一个byte一个byte的读取,导致频繁的本地JNI文件系统访问,非常低效,因为调用本地方法是非常耗时的。最好用BufferedInputStream包装一下。曾经做过一个测试,从/dev/zero下读取1MB,大概花了1s,而用BufferedInputStream包装之后只需要60ms,性能提高了94%! 这个也适用于output stream操作以及socket操作。正确的写法:73 InputStream in =

12、new BufferedInputStream(new FileInputStream(file); 无限使用heap内存错误的写法:74 byte pdf = toPdf(file); 这里有一个前提,就是文件大小不能讲JVM的heap撑爆。否则就等着OOM吧,尤其是在高并发的服务器端代码。最好的做法是采用Stream的方式边读取边存储(本地文件或database)。正确的写法:75 File pdf = toPdf(file); 另外,对于服务器端代码来说,为了系统的安全,至少需要对文件的大小进行限制。不指定超时时间错误的代码:76 Socket socket = . 77 socket.

13、connect(remote); 78 InputStream in = socket.getInputStream(); 79 int i = in.read(); 这种情况在工作中已经碰到不止一次了。个人经验一般超时不要超过20s。这里有一个问题,connect可以指定超时时间,但是read无法指定超时时间。但是可以设置阻塞(block)时间。正确的写法:80 Socket socket = . 81 socket.connect(remote, 20000); / fail after 20s 82 InputStream in = socket.getInputStream(); 83

14、 socket.setSoTimeout(15000); 84 int i = in.read(); 另外,文件的读取(FileInputStream, FileChannel, FileDescriptor, File)没法指定超时时间, 而且IO操作均涉及到本地方法调用, 这个更操作了JVM的控制范围,在分布式文件系统中,对IO的操作内部实际上是网络调用。一般情况下操作60s的操作都可以认为已经超时了。为了解决这些问题,一般采用缓存和异步/消息队列处理。频繁使用计时器错误代码:85 for (.) 86 long t = System.currentTimeMillis(); 87 long t = System.nanoTime(); 88 Date d = new Date(); 89 Calendar c = new GregorianCalendar(); 90 每次new一个Date或Calendar都会涉及一次本地调用来获取当前时间(尽管这个本地调用相对其他本地方法调用

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号