博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
神奇的代码-常见错误代码注意点
阅读量:6543 次
发布时间:2019-06-24

本文共 10706 字,大约阅读时间需要 35 分钟。

  hot3.png

 

import java.math.BigDecimal;import java.util.concurrent.CountDownLatch;import java.util.concurrent.atomic.AtomicInteger;import org.junit.Test;/** * 常见错误代码注意点 * @author Yuanqy * @time 2015年5月10日 9:23:00 */public class ExceptionTest {    /**     * 用例1:入箱与拆箱 
* Integer、Short、Byte、Character、Long这几个包装类的valueOf方法的实现是类似的:会有缓存cache.high,cache.low;
* Double、Float的valueOf方法的实现是类似的:要么直接赋值,要么通过String转。
* Boolean的valueOf方法的实现是个三目运算,形如` return (b ? TRUE : FALSE); */ @Test public void test1() { System.out.println("==test1=======================================");// //JDK,源代码:// public static Integer valueOf(int i) {// assert IntegerCache.high >= 127;// if (i >= IntegerCache.low && i <= IntegerCache.high)// return IntegerCache.cache[i + (-IntegerCache.low)];// return new Integer(i);// } Integer i1 = 128; Integer i2 = 128; Integer i3 = 127; Integer i4 = 127; System.out.println("i1 == i2:" + (i1 == i2));// false System.out.println("i3 == i4:" + (i3 == i4));// true } /** * 用例2:入箱与拆箱
* 在java代码中,很多场景会用到装箱和拆箱操作,稍不留神,就会掉坑里。
* 保证不出异常,就在运算过程中用同种类型。装箱就全部装箱。不装箱就全部不装箱。 */ @Test public void test2() { class TestBean { private Integer test; public Integer getTest() { return test; } public void setTest(Integer test) { this.test = test; } } try { System.out.println("==test2======================================="); TestBean bean = new TestBean(); bean.setTest(bean != null ? bean.getTest() : new Integer(1)); // 这行正常 bean.setTest(bean != null ? bean.getTest() : 1);// 这行异常【很经典的异常】,原因是三元表达式的执行过程和 int/Integer 的入箱与拆箱 过程照成的。 } catch (Exception e) { e.printStackTrace(); throw e; } } /** * 用例3:注意数据溢出 */ @Test public void test3() { System.out.println("==test3======================================="); int s = 1; for (int i = 10; i <= 49; i++) { s = s * i; System.out.println(s + "==" + Integer.toBinaryString(s)); } System.out.println("结果是:" + s);// 结果是:0 } /** * 用例4:不要相信 get/Select,要保证操作原子性 * 并且:基本数据类型的 ++ ,-- 运算符 也非线程安全,是非原子性的。 * 计数操作,使用AtomicXX类操作 * 还有:Thread、Runnable、Callable、Future、FutureTask,这些多线程操作都有线程安全问题,需要特殊处理。 * 【网上误人子弟的真JB多,特别是IO,多线程的文章】。 * @throws InterruptedException */ @Test public void test4() throws InterruptedException { System.out.println("==test4======================================="); int sum = 100; final CountDownLatch latch = new CountDownLatch(sum); Thread t = new Thread() { private AtomicInteger count = new AtomicInteger(0);// 计数不能使用int做++count private BigDecimal money = BigDecimal.ZERO; public BigDecimal getMoney() { return money; } public void setMoney(BigDecimal money) { this.money = money; } @Override public void run() { BigDecimal curM = BigDecimal.ZERO; // synchronized (curM) {//加同步块或读写锁 try { curM = getMoney(); curM = curM.add(BigDecimal.ONE); setMoney(curM); System.out.println(count.addAndGet(1) + ":getMoney=" + getMoney().toPlainString()); latch.countDown(); } catch (Exception e) { e.printStackTrace(); } // } } }; // t只实例一次 for (int i = 0; i < sum; i++) { new Thread(t).start(); } latch.await(); System.out.println("结果:执行了100次加操作,结果却不是100。"); } /** * 用例5:涉及到小数操作,不允许出现float double浮点数类型 * 特别是金融场景 */ @Test public void test5() { System.out.println("==test5======================================="); System.out.println(0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1 + 0.1); System.out.println(0.1 * 10); } /** * 浮点数操作,最好使用BigDecimal 或 String */ @Test public void test6() { System.out.println("==test6======================================="); Double d=123456789.98D; System.out.println(new BigDecimal(d).toString());// 错 System.out.println(new Double(d).toString());// 错 System.out.println(new BigDecimal(new Double(d).toString()).toString());// 对 System.out.println(new BigDecimal(d).toPlainString());// 错 } /** * 代码都是假随机。 * 可以预测的,甚至可以输出想要的字符。 */ @Test public void test7() { System.out.println("==test7======================================="); class RandomBuild { public String getStr(long seed) { Random ran = new Random(seed); StringBuilder sb = new StringBuilder(); while (true) { int k = ran.nextInt(27); System.out.println("char:" + k + ",number:" + k); if (k == 0) break; k += 96; sb.append((char) k); } return sb.toString(); } } RandomBuild rb = new RandomBuild(); System.out.println(rb.getStr(-229985452) + " " + rb.getStr(-147909649)); }}

 

执行结果控制台:

==test1=======================================i1 == i2:falsei3 == i4:true==test2=======================================java.lang.NullPointerException	at ExceptionTest.test2(ExceptionTest.java:60)	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)	at java.lang.reflect.Method.invoke(Method.java:606)	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)	at org.junit.runners.ParentRunner.run(ParentRunner.java:309)	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)==test3=======================================10==1010110==11011101320==1010010100017160==100001100001000240240==1110101010011100003603600==110110111111001001000057657600==11011011111100100100000000980179200==111010011011000101100100000000463356416==11011100111100100001000000000213837312==1100101111101110011000000000-18221056==11111110111010011111100000000000-382642176==11101001001100010101100000000000171806720==1010001111011001000000000000-343412736==11101011100001111111000000000000348028928==10100101111101000000000000000110788608==110100110101000000000000000-1414463488==10101011101100010000000000000000464191488==11011101010110000000000000000112459776==110101101000000000000000000-1033633792==11000010011001000000000000000000-944242688==11000111101110000000000000000000793247744==101111010010000000000000000000-385875968==11101001000000000000000000000000150994944==1001000000000000000000000000838860800==110010000000000000000000000000-704643072==11010110000000000000000000000000402653184==110000000000000000000000000002013265920==1111000000000000000000000000000-805306368==11010000000000000000000000000000-1342177280==10110000000000000000000000000000-2147483648==10000000000000000000000000000000-2147483648==100000000000000000000000000000000==00==00==00==00==00==00==00==0结果是:0==test4=======================================1:getMoney=12:getMoney=23:getMoney=34:getMoney=45:getMoney=56:getMoney=67:getMoney=78:getMoney=89:getMoney=910:getMoney=1011:getMoney=1112:getMoney=1213:getMoney=1314:getMoney=1415:getMoney=1516:getMoney=1617:getMoney=1718:getMoney=1819:getMoney=1920:getMoney=2021:getMoney=2122:getMoney=2223:getMoney=2224:getMoney=2325:getMoney=2426:getMoney=2527:getMoney=2628:getMoney=2729:getMoney=2830:getMoney=2931:getMoney=3032:getMoney=3133:getMoney=3234:getMoney=3235:getMoney=3336:getMoney=3337:getMoney=3438:getMoney=3539:getMoney=3640:getMoney=3741:getMoney=3842:getMoney=3944:getMoney=3943:getMoney=3847:getMoney=4249:getMoney=4446:getMoney=4151:getMoney=4653:getMoney=4845:getMoney=4054:getMoney=4957:getMoney=5255:getMoney=5060:getMoney=5561:getMoney=5662:getMoney=5752:getMoney=4750:getMoney=4564:getMoney=5948:getMoney=4367:getMoney=6168:getMoney=6269:getMoney=6371:getMoney=6566:getMoney=6072:getMoney=6674:getMoney=6865:getMoney=5975:getMoney=6976:getMoney=7077:getMoney=7163:getMoney=5879:getMoney=7380:getMoney=7459:getMoney=5481:getMoney=7582:getMoney=7658:getMoney=5384:getMoney=7885:getMoney=7956:getMoney=5183:getMoney=7778:getMoney=7289:getMoney=8373:getMoney=6791:getMoney=8470:getMoney=6499:getMoney=8598:getMoney=9096:getMoney=8997:getMoney=8995:getMoney=8794:getMoney=86100:getMoney=8593:getMoney=8592:getMoney=8590:getMoney=8388:getMoney=8287:getMoney=8186:getMoney=80结果:执行了100次加操作,结果却不是100。==test5=======================================0.99999999999999991.0==test6=======================================123456789.980000004172325134277343751.2345678998E8123456789.98123456789.98000000417232513427734375==test7=======================================char:8,number:8char:5,number:5char:12,number:12char:12,number:12char:15,number:15char:0,number:0char:23,number:23char:15,number:15char:18,number:18char:12,number:12char:4,number:4char:0,number:0hello world

 

转载于:https://my.oschina.net/jweb/blog/1814018

你可能感兴趣的文章
网络故障一般排查操作
查看>>
ViewPager2:官方Viewpager升级版来临
查看>>
【计算机本科补全计划】图的连通性check by 并查集Union Find
查看>>
你距离月薪50k的程序员,只差了一个完善的职业规划
查看>>
Java并发编程 synchronized保证线程安全的原理
查看>>
证书过期?私钥泄露?掌控您的证书和私钥,维护网站安全和声誉!
查看>>
JDK源码阅读-Object类
查看>>
第六章:nginx实现动静分离
查看>>
两分钟带你快速掌握Flutter的路由与导航
查看>>
JavaScript移动端滑动操作封装
查看>>
H5页面加载后表单获取焦点并唤起软键盘?
查看>>
区块链技术开发能否带来区块链治理体系创新研发?
查看>>
页面布局
查看>>
Kotlin JVM常用注解参数解析
查看>>
干货 | 个性化推荐系统五大研究热点之深度学习(一)
查看>>
Spark 源码系列(五)分布式缓存
查看>>
删除GitHub项目中指定的文件或者目录
查看>>
node.js 的企业级开发框架loopback
查看>>
Go语言学习教程:xorm表基本操作及高级操作
查看>>
私藏的安卓开发过程中好用的组件
查看>>