??xml version="1.0" encoding="utf-8" standalone="yes"?>97精品视频在线,欧美在线一级视频,91福利精品第一导航http://www.aygfsteel.com/weiwei/category/53448.html合抱之木Q生于毫末;?ji)层之台Qv于篏土;千里之行Q始于下?/description>zh-cnSat, 12 Oct 2013 06:29:56 GMTSat, 12 Oct 2013 06:29:56 GMT60JAVA垃圾回收http://www.aygfsteel.com/weiwei/articles/404814.htmlliwei5891liwei5891Wed, 09 Oct 2013 13:35:00 GMThttp://www.aygfsteel.com/weiwei/articles/404814.htmlhttp://www.aygfsteel.com/weiwei/comments/404814.htmlhttp://www.aygfsteel.com/weiwei/articles/404814.html#Feedback0http://www.aygfsteel.com/weiwei/comments/commentRss/404814.htmlhttp://www.aygfsteel.com/weiwei/services/trackbacks/404814.html哪些内存需要回Ӟ
什么时候回Ӟ
如何回收Q?/div>
一Q哪些内存需要回Ӟ
JAVA内存?sh)不需要考虑内存回收问题的区域:(x)
E序计数器、虚拟机栈,本地Ҏ(gu)?/div>
Q随U程生灭Q栈帧分配多内存在cȝ构确定是已知,因此它们的内存分配与回收具备定性。方法结束或U程l束Ӟ内存自然p着回收?jin)?j)
需要考虑内存回收问题的区域:(x)
JAVA堆和Ҏ(gu)?/div>
(创徏哪些对象Q创建多对象,需要在q行期间才知道。不再用创徏对象的类定义要从Ҏ(gu)区回?
二:(x)堆中对象的回?/div>
d的对象才?x)被回?/div>
如何判断对象已死
a.引用计数法Q?/div>
l对象添加一个引用计数器Q每当有一个地方引用它Ӟ计数器值就?。引用失效时Q计数器值就?.M时候计数器?的对象就是不可能再被使用的?/div>
优点Q引用计数算法实现简单,判定效率也高?使用在COM,FlashPlayer,Python{语a?
~点Q它很难解决对象之间怺循环引用的问题。(因此JAVA中没有选用它来理内存Q?/div>
b.Ҏ(gu)索算?/div>
对于M"GC Roots"都没有\径到辑֯象时Q该对象是不可用的?/div>
L的程序语a都用的是Ҏ(gu)索算法,包括JAVA语言?/div>
哪些对象才是"GC Roots"
  • 虚拟机栈(栈中的本地变量?中引用的对象
  • Ҏ(gu)Z的类?rn)态属性引用的对象
  • Ҏ(gu)Z的常量引用的对象
  • 本地Ҏ(gu)栈中JNI的引用的对象
JAVA中的引用分ؓ(f)Q强引用QStrong ReferenceQ、Y引用QSoft ReferenceQ、弱引用QWeak ReferenceQ、虚引用QPhantom ReferenceQ四U,强度依次减弱
  • 强引用:(x)代码中存在,cM "Object obj = new Object()"q类。只要强引用存在QGC永q不?x)回收掉被引用的对象?/li>
  • 软引用:(x)描述一些还有用Q但非必需的对象。在pȝ要发生内存溢出异常之前Q将把这些对象列q回范围之中q进行第二次回收。如果这ơ回收还没有_的内存,才会(x)抛出内存溢出异常。通过 SoftReferencecL实现软引用?/li>
  • 弱引用:(x)也用于描q非必需对象Q但它的强度要比软引用更׃些,被弱引用兌的对象只能生成到下一ơGC发生之前。当GC工作Ӟ无论当前内存是否_Q都?x)回收弱引用兌的对象。通过 WeakReferencecL实现弱引?/li>
  • 虚引用:(x)也称为幽灵引用或qd(jing)引用。设|虚引用兌的唯一目录是希望q个对象被回收时收到一个系l通知。通过PhantomReference来实现虚引用
I竟什么样的对象才?x)死掉呢Q?/div>
要真正宣告一个对象死亡,臛_要经历两ơ标记过E?/strong>Q如果对象在q行Ҏ(gu)索后发现没有?GC Roots 相连接的引用链,那它?yu)?x)被第一ơ标记ƈ攑ֈ“卛_被回收的集合”中?/div>
与此同时q行一ơ筛选,{选的条g是此对象是否有必要执?finalize() Ҏ(gu)?当对象没有覆?finalize()Ҏ(gu)Q或?finalize() Ҏ(gu)已经被虚拟机调用q,虚拟机将q两U情况都视ؓ(f) "没有必要执行"?如果q个对象被判定ؓ(f)有必要执?finalize()Ҏ(gu)Q那么这个对象将?x)被攄C个名?F-Queue 的队列之中,在E后׃条由虚拟动徏立的Q低优先U的 Finalizer U程L行(触发finalize()Ҏ(gu)而不{待Q。finalize()Ҏ(gu)是对象逃脱M命运的最后一ơ机?x)。对象要在finalize()Ҏ(gu)中拯救自己,只要重新与引用链上Q何一个对象徏立关联即可,q样的话W二ơ标记时它被U除?#8220;卛_回收的集?#8221;。如果对象这个时候还没有逃脱Q那q的离Mq了(jin)?/div>
三:(x)Ҏ(gu)区的回收
主要回收两部份内容:(x)废弃帔R、无用的c?/div>
帔R回收与堆中对象回收类伹{?/div>
无用的类的判断需同时满3条:(x)
  • 该类所有的实例都已l被回收Q也是说堆中不存在该类的Q何实?/li>
  • 加蝲该类?ClassLoader 已经被回?/li>
  • 该类对应?java.lang.Class 对象没有在Q何地方被引用Q无法在M地方通过反射讉K该类的方?/li>
虚拟机对满上述3个条件的无用c进行回收。(只是可以Q不?x)是必然回收Q是否对c进行回ӞHotSpot虚拟Z(jin) -Xnoclassgc参数q行控制。还可以使用 -verbose:class ?XX:+TraceClassLoading ?-XX:+TraceClassUnLoading查看cȝ加蝲和卸载信息?/div>
四:(x)垃圾攉法
4.1 标记-清除法
标记出所有需要回收的对象Q标记完成后l一回收掉所有被标记的对象。(如何标记在堆对象回收部分有介l)(j)
它是最基础的收集算法,后箋(hu)攉法都是Zq种思\改进而得到?/div>
~点Q效率不高,产生大量不连l的内存片?/div>
Q空间碎片太多,分配较大对象时就无法扑ֈ_q箋(hu)内存I间Q而不得不提前触发另一ơ垃圾收集动作)(j)
4.2 复制法
Qؓ(f)解决效率问题Q?/div>
内存按定w划分为大相{的两块Q每ơ只使用其中的一块。当q一块内存用完了(jin)Q就还存活着的对象复制到另一块上面,然后再把已用过的内存空间一ơ清理掉?/div>
优点Q内存分配时不用考虑片的问题,实现单,q行高效
~点Q内存羃?yu)?f)原来的一半?/div>
当对象存?gu)zȝ较高Ӟ需要较多的复制操作Q效率将?x)变(sh)。若不想费50%的空_(d)需要额外的I间q行分配担保
现在的商业虚拟机都采用这U收集算法来回收新生?IBM研究表明Q新生代对象98%是朝夕死?。不q,q不是按1Q?的比例来划分内存I间。而是内存分Z块较大的 Eden I间 和两块较?yu)的SurvivorI间。每ơ只使用 Eden 和其中的一块Survivor。当回收ӞEden和Survivor中还存活着的对象一ơ性拷贝到另外一块SurvivorI间上,最后清理掉刚才的Eden和Survivor。默认Eden和Survivor比例?8:1。(98%是一般场景,另外一些场景下Q当SurvivorI间不够Ӟ需依赖其它内存【老年代】进行分配担保)(j)
4.3 标记-整理法
复制法的缺点,军_老年代不能用复制算?/div>
Ҏ(gu)老年代特点,提出?#8220;标记-整理法”?/div>
标记q程仍然?#8220;标记-清除”法一P但后l步骤不是直接对可回收对象进行清理,而是让所有存?gu)zȝ对象都向一端移动,然后直接清理掉端边界以外的内存?/div>
4.4 分代攉法
当前虚拟机的垃圾攉都采?#8220;分代攉”法?/div>
Ҏ(gu)对象的存?gu)zd期将内存划分为几块。一般将堆分为新生代和老年代,q样Ҏ(gu)各个q代的特炚w用最适当的收集算法?/div>
新生代采用复制算?/div>
老年代采?#8220;标记-清理”?#8220;标记-整理”法
五:(x)垃圾攉?/div>
法是内存回收的Ҏ(gu)论,垃圾攉器是内存回收的具体实现?/div>
Serial攉?/div>
~点Q单U程攉器,垃圾攉时必L停其它所有的工作U程QStop the worldQ?/div>
优点Q简单而高效,对于Client模式下的虚拟机来说是一个很好的选择。(也是Client模式下的默认新生代收集器Q?/div>
ParNew 攉?/div>
其实是 Serial 攉器的多线E版?/div>
是Server模式下的虚拟机的首选新生代攉器。(一个重要原因是Q目前除?jin)Serial攉器外Q只有它能与CMS攉器配合工作)(j)
Paraller Scavenge 攉?/div>
q行的多U程攉?/div>
它的x(chng)点与其它攉器的不同Q它x(chng)的是吞吐?/div>
吞吐?q行用户代码旉/(q用用户代码旉+垃圾攉旉)
Serial Old 攉?/div>
是Serial攉器的老年代版本,同样是单U程攉器。?#8220;标记-整理”法
Parallel Old 攉?/div>
是Parallel Scavenge攉器的老年代版本,使用多线和和“标记-整理法”QJDK1.6才提供?/div>
注重吞吐量及(qing)CPU资源敏感的场合,可以优先考虑Parallel Scavenge加Parallel Oldl合?/div>
CMS攉?QConcurrent Mark SweepQ?/div>
是一U以获取最短回收停时间ؓ(f)目标的收集器?/div>
对于B/Sc重视服务器响应速度Q希望停时间最短类应用比较适合?/div>
Z“标记-清除法实现”
内存回收q程与用L(fng)Evq发的执行?/div>
~点Q?/div>
对CPU资源非常敏感?/div>
无法处理动垃圾
攉l束时会(x)产生大量I间片
G1攉器(Garbage FirstQ`
JDK1.7正式发布Ӟ很可能会(x)有一个成熟的商业版本随之发布?/div>
相对CMS的改q:(x)
Z“标记-整理”法实现Q不?x)生空间碎?/div>
可以非常_的控制停?/div>
可以实现基本不牺牲吞吐量的前提下完成低停的内存回收


liwei5891 2013-10-09 21:35 发表评论
]]>Enum单例?/title><link>http://www.aygfsteel.com/weiwei/articles/342916.html</link><dc:creator>liwei5891</dc:creator><author>liwei5891</author><pubDate>Thu, 13 Jan 2011 03:47:00 GMT</pubDate><guid>http://www.aygfsteel.com/weiwei/articles/342916.html</guid><wfw:comment>http://www.aygfsteel.com/weiwei/comments/342916.html</wfw:comment><comments>http://www.aygfsteel.com/weiwei/articles/342916.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/weiwei/comments/commentRss/342916.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/weiwei/services/trackbacks/342916.html</trackback:ping><description><![CDATA[Enum<br /><br /><div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080"> 1</span> <span style="color: #0000ff">package</span><span style="color: #000000"> com.study.enums;<br /></span><span style="color: #008080"> 2</span> <span style="color: #000000"><br /></span><span style="color: #008080"> 3</span> <span style="color: #000000"><br /></span><span style="color: #008080"> 4</span> <span style="color: #000000"><br /></span><span style="color: #008080"> 5</span> <span style="color: #000000"></span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">enum</span><span style="color: #000000"> SexEnum {<br /></span><span style="color: #008080"> 6</span> <span style="color: #000000">    FEMAIL(</span><span style="color: #000000">"</span><span style="color: #000000">00</span><span style="color: #000000">"</span><span style="color: #000000">),<br /></span><span style="color: #008080"> 7</span> <span style="color: #000000">    MAIL(</span><span style="color: #000000">"</span><span style="color: #000000">01</span><span style="color: #000000">"</span><span style="color: #000000">);<br /></span><span style="color: #008080"> 8</span> <span style="color: #000000">    <br /></span><span style="color: #008080"> 9</span> <span style="color: #000000">    </span><span style="color: #0000ff">private</span><span style="color: #000000"> String value;<br /></span><span style="color: #008080">10</span> <span style="color: #000000">    </span><span style="color: #0000ff">private</span><span style="color: #000000"> SexEnum(String value) {<br /></span><span style="color: #008080">11</span> <span style="color: #000000">        </span><span style="color: #0000ff">this</span><span style="color: #000000">.value </span><span style="color: #000000">=</span><span style="color: #000000"> value;<br /></span><span style="color: #008080">12</span> <span style="color: #000000">    }<br /></span><span style="color: #008080">13</span> <span style="color: #000000">    <br /></span><span style="color: #008080">14</span> <span style="color: #000000">    </span><span style="color: #0000ff">public</span><span style="color: #000000"> String getValue(){<br /></span><span style="color: #008080">15</span> <span style="color: #000000">        </span><span style="color: #0000ff">return</span><span style="color: #000000"> value;<br /></span><span style="color: #008080">16</span> <span style="color: #000000">    }<br /></span><span style="color: #008080">17</span> <span style="color: #000000">    <br /></span><span style="color: #008080">18</span> <span style="color: #000000">    </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">static</span><span style="color: #000000"> SexEnum fromValue(String value){<br /></span><span style="color: #008080">19</span> <span style="color: #000000">        SexEnum[] enums </span><span style="color: #000000">=</span><span style="color: #000000"> SexEnum.values();<br /></span><span style="color: #008080">20</span> <span style="color: #000000">        <br /></span><span style="color: #008080">21</span> <span style="color: #000000">        </span><span style="color: #0000ff">if</span><span style="color: #000000">(enums</span><span style="color: #000000">!=</span><span style="color: #0000ff">null</span><span style="color: #000000">){<br /></span><span style="color: #008080">22</span> <span style="color: #000000">            </span><span style="color: #0000ff">for</span><span style="color: #000000">(SexEnum item:enums){<br /></span><span style="color: #008080">23</span> <span style="color: #000000">                </span><span style="color: #0000ff">if</span><span style="color: #000000">(item.getValue().equals(value))<br /></span><span style="color: #008080">24</span> <span style="color: #000000">                    </span><span style="color: #0000ff">return</span><span style="color: #000000"> item;<br /></span><span style="color: #008080">25</span> <span style="color: #000000">            }<br /></span><span style="color: #008080">26</span> <span style="color: #000000">        }<br /></span><span style="color: #008080">27</span> <span style="color: #000000">        <br /></span><span style="color: #008080">28</span> <span style="color: #000000">        </span><span style="color: #0000ff">return</span><span style="color: #000000"> </span><span style="color: #0000ff">null</span><span style="color: #000000">;<br /></span><span style="color: #008080">29</span> <span style="color: #000000">    }<br /></span><span style="color: #008080">30</span> <span style="color: #000000">}<br /></span><span style="color: #008080">31</span> <span style="color: #000000"></span></div><br /><div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080"> 1</span> <span style="color: #0000ff">package</span><span style="color: #000000"> com.study.enums;<br /></span><span style="color: #008080"> 2</span> <span style="color: #000000"><br /></span><span style="color: #008080"> 3</span> <span style="color: #000000"></span><span style="color: #0000ff">import</span><span style="color: #000000"> junit.framework.Assert;<br /></span><span style="color: #008080"> 4</span> <span style="color: #000000"><br /></span><span style="color: #008080"> 5</span> <span style="color: #000000"></span><span style="color: #0000ff">import</span><span style="color: #000000"> org.junit.Test;<br /></span><span style="color: #008080"> 6</span> <span style="color: #000000"><br /></span><span style="color: #008080"> 7</span> <span style="color: #000000"></span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">class</span><span style="color: #000000"> SexEnumTest {<br /></span><span style="color: #008080"> 8</span> <span style="color: #000000"><br /></span><span style="color: #008080"> 9</span> <span style="color: #000000">    @Test<br /></span><span style="color: #008080">10</span> <span style="color: #000000">    </span><span style="color: #0000ff">public</span><span style="color: #000000"> </span><span style="color: #0000ff">void</span><span style="color: #000000"> testGetValue() {<br /></span><span style="color: #008080">11</span> <span style="color: #000000">        System.out.println(SexEnum.FEMAIL.getValue());<br /></span><span style="color: #008080">12</span> <span style="color: #000000">        <br /></span><span style="color: #008080">13</span> <span style="color: #000000">        System.out.println(SexEnum.MAIL.getValue());<br /></span><span style="color: #008080">14</span> <span style="color: #000000">        <br /></span><span style="color: #008080">15</span> <span style="color: #000000">        System.out.println(SexEnum.fromValue(</span><span style="color: #000000">"</span><span style="color: #000000">00</span><span style="color: #000000">"</span><span style="color: #000000">).getValue());<br /></span><span style="color: #008080">16</span> <span style="color: #000000">        <br /></span><span style="color: #008080">17</span> <span style="color: #000000">        System.out.println(SexEnum.fromValue(</span><span style="color: #000000">"</span><span style="color: #000000">01</span><span style="color: #000000">"</span><span style="color: #000000">).getValue());<br /></span><span style="color: #008080">18</span> <span style="color: #000000">        <br /></span><span style="color: #008080">19</span> <span style="color: #000000">        <br /></span><span style="color: #008080">20</span> <span style="color: #000000">        Assert.assertEquals(SexEnum.FEMAIL, SexEnum.fromValue(</span><span style="color: #000000">"</span><span style="color: #000000">00</span><span style="color: #000000">"</span><span style="color: #000000">));<br /></span><span style="color: #008080">21</span> <span style="color: #000000">        <br /></span><span style="color: #008080">22</span> <span style="color: #000000">        Assert.assertEquals(SexEnum.MAIL, SexEnum.fromValue(</span><span style="color: #000000">"</span><span style="color: #000000">01</span><span style="color: #000000">"</span><span style="color: #000000">));<br /></span><span style="color: #008080">23</span> <span style="color: #000000">    }<br /></span><span style="color: #008080">24</span> <span style="color: #000000"><br /></span><span style="color: #008080">25</span> <span style="color: #000000">}<br /></span><span style="color: #008080">26</span> <span style="color: #000000"></span></div><br /><br />l果Q?br /><br />00<br />01<br />00<br />01<br /><br /><br /><img src ="http://www.aygfsteel.com/weiwei/aggbug/342916.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/weiwei/" target="_blank">liwei5891</a> 2011-01-13 11:47 <a href="http://www.aygfsteel.com/weiwei/articles/342916.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中只有传?/title><link>http://www.aygfsteel.com/weiwei/articles/319207.html</link><dc:creator>liwei5891</dc:creator><author>liwei5891</author><pubDate>Fri, 23 Apr 2010 09:12:00 GMT</pubDate><guid>http://www.aygfsteel.com/weiwei/articles/319207.html</guid><wfw:comment>http://www.aygfsteel.com/weiwei/comments/319207.html</wfw:comment><comments>http://www.aygfsteel.com/weiwei/articles/319207.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/weiwei/comments/commentRss/319207.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/weiwei/services/trackbacks/319207.html</trackback:ping><description><![CDATA[java中只有传?br /><br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #000000;">package sinosoft;<br /><br />import org.junit.Test;<br /><br />public class PassValueTest {<br />    <br />    /**<br />     * q行l果?br />     *  Hello World!<br />        hi World!<br />        Hello World!<br />        要理解这点,p理解在Java中只有传?br />        对于参数传递,如果是简单数据类型,那么它传递的是值拷贝,<br />        对于cȝ实例它传递的是类的引用的拯<br />        <br />        对类来说Q引用与引用的拷贝都指向对象的同一个内存块Q因此对引用操作Q引响的是同一个对?br />        但像changҎ(gu)中,对引用的拯重新赋给一个对象,那就与原先对象无关了(jin)。自然不?x)?jing)响到原先对象<br />     */<br />    @Test<br />    public void test(){<br />        StringBuffer bf = new StringBuffer("Hello World!");<br />        System.out.println(bf.toString());<br />        <br />        change(bf);<br />        <br />        System.out.println(bf.toString());<br />    }<br />    <br />    public void change(StringBuffer bf){<br />        bf = new StringBuffer("hi");<br />        bf.append(" World!");<br />        <br />        System.out.println(bf.toString());<br />    }      <br />}<br /></span></div><img src ="http://www.aygfsteel.com/weiwei/aggbug/319207.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/weiwei/" target="_blank">liwei5891</a> 2010-04-23 17:12 <a href="http://www.aygfsteel.com/weiwei/articles/319207.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用BigDecimal_计算http://www.aygfsteel.com/weiwei/articles/310919.htmlliwei5891liwei5891Wed, 27 Jan 2010 04:06:00 GMThttp://www.aygfsteel.com/weiwei/articles/310919.htmlhttp://www.aygfsteel.com/weiwei/comments/310919.htmlhttp://www.aygfsteel.com/weiwei/articles/310919.html#Feedback0http://www.aygfsteel.com/weiwei/comments/commentRss/310919.htmlhttp://www.aygfsteel.com/weiwei/services/trackbacks/310919.html

Java 点数精计?BigDecimal的用?

java.math.BigDecimal的用法?

Java 点?_计算  

如果我们~译q行下面q个E序?x)看C么?

public class Test{

    public static void main(String args[]){

        System.out.println(0.05+0.01);

        System.out.println(1.0-0.42);

        System.out.println(4.015*100);

        System.out.println(123.3/100);

    }

};

你没有看错!l果实?

0.060000000000000005

0.5800000000000001

401.49999999999994

1.2329999999999999

Java中的单QҎ(gu)cdfloat和double不能够进行运。不光是JavaQ在其它很多~程语言中也有这L(fng)问题。在大多数情况下Q计的l果是准的Q但是多试几ơ(可以做一个@环)(j)可以试出类g面的错误。现在终于理解ؓ(f)什么要有BCD码了(jin)?

q个问题相当严重Q如果你?.999999999999元,你的计算机是不会(x)认ؓ(f)你可以购?0元的商品的?

在有的编E语a中提供了(jin)专门的货币类型来处理q种情况Q但是Java没有。现在让我们看看如何解决q个问题?

四舍五入

我们的第一个反应是做四舍五入。MathcM的roundҎ(gu)不能讄保留几位数Q我们只能象q样Q保留两位)(j)Q?

public double round(double value){

    return Math.round(value*100)/100.0;

}

非常不幸Q上面的代码q不能正常工作,l这个方法传?.015它将q回4.01而不?.02Q如我们在上面看到的

4.015*100=401.49999999999994

因此如果我们要做到精的四舍五入Q不能利用简单类型做Mq算

java.text.DecimalFormat也不能解册个问题:(x)

System.out.println(new java.text.DecimalFormat("0.00").format(4.025));

输出?.02

BigDecimal

在《Effective Java》这本书中也提到q个原则Qfloat和double只能用来做科学计或者是工程计算Q在商业计算中我们要?java.math.BigDecimal。BigDecimal一共有4个够造方法,我们不关?j)用BigInteger来够造的那两个,那么q有两个Q它们是Q?

BigDecimal(double val)

          Translates a double into a BigDecimal.

BigDecimal(String val)

          Translates the String repre sentation of a BigDecimal into a BigDecimal.

上面的API要描q相当的明确Q而且通常情况下,上面的那一个用v来要方便一些。我们可能想都不惛_用上?jin),会(x)有什么问题呢Q等到出?jin)问题的时候,才发C面哪个够造方法的详细说明中有q么一D:(x)

Note: the results of this constructor can be somewhat unpredictable. One might assume that new BigDecimal(.1) is exactly equal to .1, but it is actually equal to .1000000000000000055511151231257827021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed in to the constructor is not exactly equal to .1, appearances nonwithstanding.

The (String) constructor, on the other hand, is perfectly predictable: new BigDecimal(".1") is exactly equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one.

原来我们如果需要精计,非要用String来够造BigDecimal不可Q在《Effective Java》一书中的例子是用String来够造BigDecimal的,但是书上却没有强调这一点,q也许是一个小的p吧?

解决Ҏ(gu)

现在我们已经可以解决q个问题?sh)(jin),原则是用BigDecimalq且一定要用String来够造?

但是惛_一下吧Q如果我们要做一个加法运,需要先两个QҎ(gu)转ؓ(f)StringQ然后够造成BigDecimalQ在其中一个上调用addҎ(gu)Q传入另一个作为参敎ͼ然后把运的l果QBigDecimalQ再转换为QҎ(gu)。你能够忍受q么?ch)琐的过E吗Q下面我们提供一个工L(fng)Arith来简化操作。它提供以下?rn)态方法,包括加减乘除和四舍五入:(x)

public static double add(double v1,double v2)

public static double sub(double v1,double v2)

public static double mul(double v1,double v2)

public static double div(double v1,double v2)

public static double div(double v1,double v2,int scale)

public static double round(double v,int scale)

附录

 


 

BigDecimal舍入模式(Rounding mode)
关键? bigdecimal

ROUND_CEILING
Rounding mode to round towards positive infinity.
向正无穷方向舍入
ROUND_DOWN
Rounding mode to round towards zero.
向零方向舍入
ROUND_FLOOR
Rounding mode to round towards negative infinity.
向负无穷方向舍入
ROUND_HALF_DOWN
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.
向(距离Q最q的一边舍入,除非两边Q的距离Q是相等,如果是这P向下舍入, 例如1.55 保留一位小数结果ؓ(f)1.5
ROUND_HALF_EVEN
Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.
向(距离Q最q的一边舍入,除非两边Q的距离Q是相等,如果是这P如果保留位数是奇敎ͼ使用ROUND_HALF_UP Q如果是偶数Q用ROUND_HALF_DOWN
ROUND_HALF_UP
Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.
向(距离Q最q的一边舍入,除非两边Q的距离Q是相等,如果是这P向上舍入, 1.55保留一位小数结果ؓ(f)1.6
ROUND_UNNECESSARY
Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary.
计算l果是精的Q不需要舍入模?
ROUND_UP
Rounding mode to round away from zero.
向远?的方向舍?
例子

Java代码

  1. BigDecimal n3  = new BigDecimal(1.2345678901234567890E+9);  
  2. System.out.println(n3) 
BigDecimal n3  = new BigDecimal(1.2345678901234567890E+9);
System.out.println(n3)

q样输出的结果是:1234567890.1234567165374755859375
当到?jin)后?7位之后就开始不准确?
因Doublecd本n只能_?7?
但是如果q样

Java代码

  1. BigDecimal n4  = new BigDecimal("1.23456789012345678901234567890E+9"); 
BigDecimal n4  = new BigDecimal("1.23456789012345678901234567890E+9");

l果?234567891.12345678901234567890
q样pl对_


liwei5891 2010-01-27 12:06 发表评论
]]>
java日期处理http://www.aygfsteel.com/weiwei/articles/280809.htmlliwei5891liwei5891Tue, 09 Jun 2009 03:13:00 GMThttp://www.aygfsteel.com/weiwei/articles/280809.htmlhttp://www.aygfsteel.com/weiwei/comments/280809.htmlhttp://www.aygfsteel.com/weiwei/articles/280809.html#Feedback0http://www.aygfsteel.com/weiwei/comments/commentRss/280809.htmlhttp://www.aygfsteel.com/weiwei/services/trackbacks/280809.html 工具c:(x)
package
 com.power.date;

import  java.text.ParseException;
import  java.text.SimpleDateFormat;
import  java.util.Calendar;
import  java.util.Date;

public   class  DateUtils {        
    
/**
     * 格式化日?br />      * 
@param  date
     * 
@param  pattern
     * 
@return
     
*/
    
    
public   static  String format(Date date,String pattern){
        SimpleDateFormat format 
=    new  SimpleDateFormat(pattern);        
        
return  format.format(date);
    }
    
    
/**
     * Ҏ(gu)字符串生成日?br />      * 
@param  dateStr
     * 
@param  pattern
     * 
@return
     * 
@throws  ParseException
     
*/
    
    
public   static  Date parse(String dateStr,String pattern)  throws  ParseException{
        SimpleDateFormat format 
=    new  SimpleDateFormat(pattern);    
        
return  format.parse(dateStr);
    }
    
    
/**
     * 比较日期前后
     * 
@param  date 
     * 
@param  when 
     * 
@return  date在when之前Q返回false,否则q回true
     
*/
    
public   static   boolean  after(Date date,Date when){
        
return  date.after(when);
    }
    
/**
     * d(或减?旉
     * 
@param  date
     * 
@param  field 要添?或减?的字D?q或月或日或)
     * 
@param  amount 要添?或减?的数量,amount为正数时Q是dQؓ(f)负数时是减小
     * 
@return  日期
     
*/
    
public   static  Date add(Date date, int  field, int  amount){        
        Calendar ca 
=  Calendar.getInstance();
        ca.setTime(date);
        ca.add(field, amount);        
        
return  ca.getTime();
    }
    
    
/**
     * d(或减?旉
     * 
@param  date
     * 
@param  field 要添?或减?的字D?q或月或日或)
     * 
@param  amount 要添?或减?的数量,amount为正数时Q是dQؓ(f)负数时是减小
     * 
@param  pattern 格式化模?br />      *  @return  格式化后的日期字W串
     
*/
    
public   static  String add(Date date, int  field, int  amount,String pattern){        
        Calendar ca 
=  Calendar.getInstance();
        ca.setTime(date);
        ca.add(field, amount);        
        
        
return  format(ca.getTime(),pattern);
    }
    
    
public   class  DatePattern{
        
public   static   final  String Y_M_D = " yyyy-MM-dd " ;
        
public   static   final  String Y_M_D_H_M_S = " yyyy-MM-dd HH:mm:ss " ;
    }
}

试c:(x)


/**
 * 
 
*/
package  com.power.date;

import  java.text.ParseException;
import  java.util.Calendar;
import  java.util.Date;

import  org.junit.Test;
import   static  junit.framework.Assert. * ;

/**
 * 
@author  liwei
 *
 
*/
public   class  TestDateUtils {
    @Test
    
public   void  testFormat(){
        Date now 
=   new  Date();
        System.out.println(DateUtils.format(now, DateUtils.DatePattern.Y_M_D));
        System.out.println(DateUtils.format(now, DateUtils.DatePattern.Y_M_D_H_M_S));
    }
    @Test
    
public   void  testParse()  throws  ParseException{
        String dateStr
= " 2009-06-09 " ;
        Date date 
=  DateUtils.parse(dateStr, DateUtils.DatePattern.Y_M_D);
        System.out.println(DateUtils.format(date, DateUtils.DatePattern.Y_M_D));
        
        dateStr
= " 2009-06-09 10:14:57 " ;
        Date date2 
=  DateUtils.parse(dateStr, DateUtils.DatePattern.Y_M_D_H_M_S);
        System.out.println(DateUtils.format(date2, DateUtils.DatePattern.Y_M_D_H_M_S));
        
    }
    
    @Test 
    
public   void  testAfter()  throws  ParseException{
        String dateStr
= " 2009-06-09 " ;
        Date date 
=  DateUtils.parse(dateStr, DateUtils.DatePattern.Y_M_D);
        
        Date now 
=   new  Date();
        
        assertTrue(DateUtils.after(now, date));
        
    }
    
    @Test 
    
public   void  testAdd()  throws  ParseException{
        String dateStr
= " 2009-06-09 " ;
        Date date 
=  DateUtils.parse(dateStr, DateUtils.DatePattern.Y_M_D);
        
        Date date2
=  DateUtils.add(date, Calendar.MONDAY,  6 );        
        assertEquals(
" 2009-12-09 " , DateUtils.format(date2, DateUtils.DatePattern.Y_M_D));
        
        assertEquals(
" 2009-12-09 " , DateUtils.add(date,Calendar.MONDAY, 6 ,DateUtils.DatePattern.Y_M_D));
        
        
        
        date2 
=  DateUtils.add(date, Calendar.MONTH,  - 2 );        
        assertEquals(
" 2009-04-09 " , DateUtils.format(date2, DateUtils.DatePattern.Y_M_D));        
        
        assertEquals(
" 2009-04-09 " , DateUtils.add(date,Calendar.MONDAY, - 2 ,DateUtils.DatePattern.Y_M_D));
        
    }
    
    
    
    
}



liwei5891 2009-06-09 11:13 发表评论
]]> վ֩ģ壺 ƽ| ڽ| | Ͼ| Ǭ| ƽ| | ܱ| | ³ƶ| ר| Ͻ| ̨| ʲ| | ͼ| | | | | | | ̨ǰ| | ˮ| Ͽ| | | | ¡| | | | | ʡ| | | | ׳| | |