﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-jimingminlovefly-文章分类-j2se</title><link>http://www.blogjava.net/jimingminlovefly/category/51413.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 24 Jan 2013 14:43:19 GMT</lastBuildDate><pubDate>Thu, 24 Jan 2013 14:43:19 GMT</pubDate><ttl>60</ttl><item><title>wait/notify/synchronized </title><link>http://www.blogjava.net/jimingminlovefly/articles/394261.html</link><dc:creator>计明敏</dc:creator><author>计明敏</author><pubDate>Tue, 15 Jan 2013 09:24:00 GMT</pubDate><guid>http://www.blogjava.net/jimingminlovefly/articles/394261.html</guid><wfw:comment>http://www.blogjava.net/jimingminlovefly/comments/394261.html</wfw:comment><comments>http://www.blogjava.net/jimingminlovefly/articles/394261.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jimingminlovefly/comments/commentRss/394261.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jimingminlovefly/services/trackbacks/394261.html</trackback:ping><description><![CDATA[<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 10px auto; word-spacing: 0px; font: 12px/21px verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(255,255,255); text-align: left; orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">为了说清道理，我们用&#8220;图书馆借书&#8221;这个经典例子来作解释。<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp; 一本书同时只能借给一个人。现在有一本书，图书馆已经把这本书借了张三。<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp; 在简单的synchrnozed 同步机制下，李四如果想借，先要去图书馆查看书有没有还回来。李四是个心急的人，他每天都去图书馆查；而张三看书看得慢，过了半个月才把书还回来，结果李四在这半个月里全都白跑了，浪费了不少交通车费<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp; 而如果使用wait/notify机制，李四就不用白忙了。他第一次去图书馆时发现书已借走，就回家静静等待(wait)；张三把书还掉后，通知(notify)李四，李四去图书馆拿书即可。整个过程中，李四没有白跑，没浪费钱。<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp; 回到计算机世界：<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp;<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 书&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&nbsp; 临界资源，需互斥地访问<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp; 张三，李四&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&nbsp; 两个竞争的线程<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />坐车去图书馆查书&nbsp;&nbsp; --&nbsp; 轮询<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 车费&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&nbsp; CPU空间<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 等待&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&nbsp; wait<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp; 通知下一个借书者&nbsp;&nbsp; --&nbsp; notify<span class="Apple-converted-space">&nbsp;</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp; 也就是说，若使用简单的synchonized机制实现互斥，会导致线程主动发起轮询，若N次轮询没有成功，就产生了N次的CPU空间浪费；如果加上了 wait/notify机制，就可以避免这些无谓的轮询，节省CPU的消耗。</p>
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 10px auto; word-spacing: 0px; font: 12px/21px verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(255,255,255); text-align: left; orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&nbsp;</p>
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 10px auto; word-spacing: 0px; font: 12px/21px verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(255,255,255); text-align: left; orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">附:</p>
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 10px auto; word-spacing: 0px; font: 12px/21px verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(255,255,255); text-align: left; orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class="ztnr1" style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; line-height: 18px; padding-top: 0px">java,wait与notify的区别<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; color: rgb(0,0,128); line-height: 18px; padding-top: 0px">wait与notify是java同步机制中重要的组成部分。结合与synchronized关键字使用，可以建立很多优秀的同步模型。<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; color: rgb(255,0,255); line-height: 18px; padding-top: 0px"><span class="Apple-converted-space">&nbsp;</span>synchronized(this){}等价与public synchronized void method(){.....}</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp;&nbsp;<span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; color: rgb(255,0,255); line-height: 18px; padding-top: 0px"><span class="Apple-converted-space">&nbsp;</span>同步分为类级别和对象级别，分别对应着类锁和对象锁</span>。类锁是每个类只有一个，<span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; color: rgb(255,0,255); line-height: 18px; padding-top: 0px">如果static的方法被synchronized关键字修饰</span>，则在这个方法被执行前必须获得类锁；对象锁类同。(static synchronized是类级别的,非static的synchronized和synchronized块都是对象级别的,即作用在同一new出来的对象上)<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp;&nbsp; 首先，<span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; color: rgb(255,0,255); line-height: 18px; padding-top: 0px">调用一个Object的wait与notify/notifyAll的时候，必须保证调用代码对该Object是同步的，也就是说必须在作用等同于synchronized(obj){......}的内部才能够去调用obj的wait与notify/notifyAll三个方法，否则就会报错：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp;&nbsp; java.lang.IllegalMonitorStateException: current thread not owner<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /></span>&nbsp;&nbsp;&nbsp;&nbsp; 在调用wait的时候，线程自动释放其占有的对象锁，同时不会去申请对象锁。当线程被唤醒的时候，它才再次获得了去获得对象锁的权利。<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />&nbsp;&nbsp;&nbsp;&nbsp; 所以，notify与notifyAll没有太多的区别，只是notify仅唤醒一个线程并允许它去获得锁，notifyAll是唤醒所有等待这个对象的线程并允许它们去获得对象锁，只要是在synchronied块中的代码，没有对象锁是寸步难行的。其实唤醒一个线程就是重新允许这个线程去获得对象锁并向下运行。</span><span class="Apple-converted-space">&nbsp;</span><span style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; color: rgb(0,0,128); line-height: 18px; padding-top: 0px">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 顺便说一下notifyall，虽然是对每个wait的对象都调用一次notify，但是这个还是有顺序的，每个对象都保存这一个等待对象链，调用的顺序就是这个链的顺序。其实启动等待对象链中各个线程的也是一个线程，在具体应用的时候，需要注意一下。<br /><br /><br /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">当线程A获得了obj锁后，发现条件condition不满足，无法继续下一处理，于是线程A就wait()。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">在另一线程B中，如果B更改了某些条件，使得线程A的condition条件满足了，就可以唤醒线程A：</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">synchronized(obj) {condition = true;obj.notify();}<span class="Apple-converted-space">&nbsp;</span></span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">需要注意的概念是：</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;调用obj的wait(), notify()方法前，必须获得obj锁，也就是必须写在synchronized(obj) {...} 代码段内。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;调用obj.wait()后，线程A就释放了obj的锁，否则线程B无法获得obj锁，也就无法在synchronized(obj) {...} 代码段内唤醒A。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;当obj.wait()方法返回后，线程A需要再次获得obj锁，才能继续执行。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;如果A1,A2,A3都在obj.wait()，则B调用obj.notify()只能唤醒A1,A2,A3中的一个（具体哪一个由JVM决定）。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;obj.notifyAll()则能全部唤醒A1,A2,A3，但是要继续执行obj.wait()的下一条语句，必须获得obj锁，因此，A1,A2,A3只有一个有机会获得锁继续执行，例如A1，其余的需要等待A1释放obj锁之后才能继续执行。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: rgb(0,0,0); text-indent: 0px; padding-top: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px" /><span style="display: inline! important; float: none; word-spacing: 0px; font: 14px/21px verdana, arial, helvetica, sans-serif; text-transform: none; color: red; text-indent: 0px; white-space: normal; letter-spacing: normal; background-color: rgb(250,250,250); orphans: 2; widows: 2; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px">&#9670;当B调用obj.notify/notifyAll的时候，B正持有obj锁，因此，A1,A2,A3虽被唤醒，但是仍无法获得obj锁。直到B退出synchronized块，释放obj锁后，A1,A2,A3中的一个才有机会获得锁继续执行。</span></span></span></p><img src ="http://www.blogjava.net/jimingminlovefly/aggbug/394261.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jimingminlovefly/" target="_blank">计明敏</a> 2013-01-15 17:24 <a href="http://www.blogjava.net/jimingminlovefly/articles/394261.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java里的按值传递与引用传递</title><link>http://www.blogjava.net/jimingminlovefly/articles/393917.html</link><dc:creator>计明敏</dc:creator><author>计明敏</author><pubDate>Mon, 07 Jan 2013 08:27:00 GMT</pubDate><guid>http://www.blogjava.net/jimingminlovefly/articles/393917.html</guid><wfw:comment>http://www.blogjava.net/jimingminlovefly/comments/393917.html</wfw:comment><comments>http://www.blogjava.net/jimingminlovefly/articles/393917.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jimingminlovefly/comments/commentRss/393917.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jimingminlovefly/services/trackbacks/393917.html</trackback:ping><description><![CDATA[<h2>按值传递还是按引用传递</h2>
<div style="float: left; margin: 3px 5px 0px 0px; color: #555555; line-height: 28px; font-family: 宋体, 'Arial Narrow', arial, serif; background-color: #ffffff">&nbsp;</div>
<div style="margin: 0px; color: #555555; line-height: 28px; font-family: 宋体, 'Arial Narrow', arial, serif; background-color: #ffffff">这个在Java里面是经常被提起的问题，也有一些争论，似乎最后还有一个所谓的结论：&#8220;在Java里面参数传递都是按值传递&#8221;。事实上，这很容易让人迷惑，下面先分别看看什么是按值传递，什么是按引用传递，只要能正确理解，至于称作按什么传递就不是个大问题了。</div>
<div style="margin: 0px; color: #555555; line-height: 28px; font-family: 宋体, 'Arial Narrow', arial, serif; background-color: #ffffff">
<div style="margin: 0px"></div>
<div style="margin: 0px"><strong style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">1：按值传递是什么</strong><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />指的是在方法调用时，传递的参数是按值的拷贝传递。示例如下：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><code style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />public class TempTest {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />private void test1(int a){<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />//做点事情<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />public static void main(String[] args) {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />TempTest t = new TempTest();<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />int a = 3;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />t.test1(a);//这里传递的参数a就是按值传递<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /></code><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />按值传递重要特点：传递的是值的拷贝，也就是说传递后就互不相关了。<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />示例如下：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><code style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />public class TempTest {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />private void test1(int a){<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />a = 5;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />System.out.println("test1方法中的a==="+a);<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />public static void main(String[] args) {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />TempTest t = new TempTest();<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />int a = 3;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />t.test1(a);//传递后，test1方法对变量值的改变不影响这里的a<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />System.out.println(&#8221;main方法中的a===&#8221;+a);<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /></code><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />运行结果是：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />test1方法中的a===5<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />main方法中的a===3</div>
<div style="margin: 0px"><strong style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">2：按引用传递是什么</strong><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />指的是在方法调用时，传递的参数是按引用进行传递，其实传递的引用的地址，也就是变量所对应的内存空间的地址。<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />示例如下：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><code style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />public class TempTest {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />private void test1(A a){</code></div>
<div style="margin: 0px">}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />public static void main(String[] args) {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />TempTest t = new TempTest();<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />A a = new A();<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />t.test1(a); //这里传递的参数a就是按引用传递<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />class A{<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />public int age = 0;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />}</div>
<div style="margin: 0px"><strong style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">3：按引用传递的重要特点</strong><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />传递的是值的引用，也就是说传递前和传递后都指向同一个引用（也就是同一个内存空间）。<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />示例如下：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><code style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第1行 public class TempTest {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第2行 private void test1(A a){<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第3行 a.age = 20;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第4行 System.out.println("test1方法中的age="+a.age);<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第5行 }<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第6行 public static void main(String[] args) {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第7行 TempTest t = new TempTest();<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第8行 A a = new A();<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第9行 a.age = 10;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第10行 t.test1(a);<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第11行 System.out.println(&#8221;main方法中的age=&#8221;+a.age);<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第12行 }<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第13行 }<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第14行 class A{<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第15行 public int age = 0;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第16行 }<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /></code><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />运行结果如下：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />test1方法中的age=20<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />main方法中的age=20</div>
<div style="margin: 0px"><strong style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">4：理解按引用传递的过程&#8212;&#8212;内存分配示意图</strong><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />要想正确理解按引用传递的过程，就必须学会理解内存分配的过程，内存分配示意图可以辅助我们去理解这个过程。<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />用上面的例子来进行分析：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />（1）：运行开始，运行第8行，创建了一个A的实例，内存分配示意如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-1.jpg" /></div>
<div style="margin: 0px">（2）：运行第9行，是修改A实例里面的age的值，运行后内存分配示意如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-2.jpg" /></div>
<div style="margin: 0px">（3）：运行第10行，是把main方法中的变量a所引用的内存空间地址，按引用传递给test1方法中的a变量。请注意：这两个a变量是完全不同的，不要被名称相同所蒙蔽。</div>
<div style="margin: 0px">内存分配示意如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-3.jpg" /></div>
<div style="margin: 0px">由于是按引用传递，也就是传递的是内存空间的地址，所以传递完成后形成的新的内存示意图如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-4.jpg" /><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />也就是说：是两个变量都指向同一个空间。</div>
<div style="margin: 0px">（4）：运行第3行，为test1方法中的变量a指向的A实例的age进行赋值，完成后形成的新的内存示意图如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-5.jpg" /></div>
<div style="margin: 0px">此时A实例的age值的变化是由test1方法引起的</div>
<div style="margin: 0px">（5）：运行第4行，根据此时的内存示意图，输出test1方法中的age=20<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />（6）：运行第11行，根据此时的内存示意图，输出main方法中的age=20</div>
<div style="margin: 0px"><strong style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">5：对上述例子的改变</strong><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />理解了上面的例子，可能有人会问，那么能不能让按照引用传递的值，相互不影响呢？就是test1方法里面的修改不影响到main方法里面呢？<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />方法是在test1方法里面新new一个实例就可以了。改变成下面的例子，其中第3行为新加的：</div>
<div style="margin: 0px"><code style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第1行 public class TempTest {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第2行 private void test1(A a){<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第3行 a = new A();//新加的一行<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第4行 a.age = 20;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第5行 System.out.println("test1方法中的age="+a.age);<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第6行 }<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第7行 public static void main(String[] args) {<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第8行 TempTest t = new TempTest();<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第9行 A a = new A();<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第10行 a.age = 10;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第11行 t.test1(a);<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第12行 System.out.println(&#8221;main方法中的age=&#8221;+a.age);<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第13行 }<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第14行}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第15行class A{<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第16行 public int age = 0;<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />第17行}<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /></code></div>
<div style="margin: 0px">运行结果为：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />test1方法中的age=20<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />main方法中的age=10</div>
<div style="margin: 0px">为什么这次的运行结果和前面的例子不一样呢，还是使用内存示意图来理解一下</div>
<div style="margin: 0px"><strong style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">6：再次理解按引用传递</strong><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />（1）：运行开始，运行第9行，创建了一个A的实例，内存分配示意如下：<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-1.jpg" /></div>
<div style="margin: 0px">（2）：运行第10行，是修改A实例里面的age的值，运行后内存分配示意如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-2.jpg" /></div>
<div style="margin: 0px">（3）：运行第11行，是把main方法中的变量a所引用的内存空间地址，按引用传递给test1方法中的a变量。请注意：这两个a变量是完全不同的，不要被名称相同所蒙蔽。</div>
<div style="margin: 0px">内存分配示意如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-3.jpg" /></div>
<div style="margin: 0px">由于是按引用传递，也就是传递的是内存空间的地址，所以传递完成后形成的新的内存示意图如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-4.jpg" /></div>
<div style="margin: 0px">也就是说：是两个变量都指向同一个空间。</div>
<div style="margin: 0px">（4）：运行第3行，为test1方法中的变量a重新生成了新的A实例的，完成后形成的新的内存示意图如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-6.jpg" /></div>
<div style="margin: 0px">（5）：运行第4行，为test1方法中的变量a指向的新的A实例的age进行赋值，完成后形成的新的内存示意图如下：</div>
<div style="margin: 0px"><img style="border-right: medium none; padding-right: 0px; border-top: medium none; padding-left: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; border-left: medium none; padding-top: 0px; border-bottom: medium none" alt="" src="http://column.ibeifeng.com/images/img/2008/10/chenchen-7.jpg" /></div>
<div style="margin: 0px">注意：这个时候test1方法中的变量a的age被改变，而main方法中的是没有改变的。</div>
<div style="margin: 0px">（6）：运行第5行，根据此时的内存示意图，输出test1方法中的age=20<br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" />（7）：运行第12行，根据此时的内存示意图，输出main方法中的age=10</div>
<div style="margin: 0px"><strong style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">7：说明</strong><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><span style="color: red">（1）：&#8220;在Java里面参数传递都是按值传递&#8221;这句话的意思是：按值传递是传递的值的拷贝，按引用传递其实传递的是引用的地址值，所以统称按值传递。</span><br style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px" /><span style="color: red">（2）：在Java里面只有</span><span style="color: #0000ff">基本类型</span><span style="color: red">和按照下面这种定义方式的</span><span style="color: #0000ff">String</span><span style="color: red">是按值传递，其它的都是按引用传递。就是直接使用双引号定义字符串方式：String str = &#8220;Java私塾&#8221;;</span><br /><span style="color: red">因为String类型比较特殊，是不可变字符串，所以，能你在调用修改方法时，调用那个方法的字符串把引用地址给了方法的形参，再修改的时候，实际上是通过形参修改的，由于修改原来字符串值时，产生了一个新的字符串，所以形参又指向了那个修字符串。而调用方法的那个字符串还是指向原来的那个字符串，所以，即使调用了修改方法，但是他指向的那个字符串还是没改变。<br /></span><a id="AjaxHolder_Comments_CommentList_ctl28_DeleteLink" href="javascript:__doPostBack('AjaxHolder$Comments$CommentList$ctl28$DeleteLink','')"></a><span style="color: red">其实只是值类型和引用类型作为参数，都是把这个变量的值复制给了方法的形参。只不过，值类型变量里面保存的是值，而引用变量里保存的是一个对象的地址。由于值类型和引用变量的这种存储方式的不同，才导致通过方法修改后得到的结果不同而已。并没有什么值传递和引用传递</span><br /></div></div><img src ="http://www.blogjava.net/jimingminlovefly/aggbug/393917.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jimingminlovefly/" target="_blank">计明敏</a> 2013-01-07 16:27 <a href="http://www.blogjava.net/jimingminlovefly/articles/393917.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java默认构造函数的作用</title><link>http://www.blogjava.net/jimingminlovefly/articles/374871.html</link><dc:creator>计明敏</dc:creator><author>计明敏</author><pubDate>Tue, 17 Apr 2012 03:32:00 GMT</pubDate><guid>http://www.blogjava.net/jimingminlovefly/articles/374871.html</guid><wfw:comment>http://www.blogjava.net/jimingminlovefly/comments/374871.html</wfw:comment><comments>http://www.blogjava.net/jimingminlovefly/articles/374871.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jimingminlovefly/comments/commentRss/374871.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jimingminlovefly/services/trackbacks/374871.html</trackback:ping><description><![CDATA[<p><span style="color: red">当new一个对象时，先判断是否调用的构造函数有参数， </span><br /><span style="color: red">如果有参数，则根据参数的个数、类型来自动调用相应 </span><br /><span style="color: red">的构造函数构造对象，分配内存，并返回对象的引用。 </span><br /><br /><span style="color: red">&#8220;如果定义了一个带参数的构造方法后，就一定要定义一个 </span><br /><span style="color: red">不带参数的构造方法，否则就不能创建新对象（无参数）。&#8221; </span><br /><span style="color: red">因为当构造一个类的对象时，编译器首先判断类是否有 </span><br /><span style="color: red">构造函数，如果没有，则自动加上一个默认构造函数， </span><br /><span style="color: red">而一旦发现有构造函数后，则不再自动加上构造函数。 </span><br /><span style="color: red">转而认为你没有用类的合法的构造函数而报出编译错误。</span><br /><br />class Person<br />{<br />private String name="";<br />private int age=0;<br /><br />public Person()<br />{<br />&nbsp;&nbsp; System.out.println("person无参数构造函数");<br />}<br /><br />public Person(String name,int age)<br />{<br />&nbsp;&nbsp; this.name=name;<br />&nbsp;&nbsp; this.age=age;<br />&nbsp;&nbsp; System.out.println("person 2 参数的构造函数");&nbsp;&nbsp;<br />}<br />}</p>
<p>class Student extends Person<br />{</p>
<p>private String school;<br />private String grade;<br /><br />public Student()<br />{<br />&nbsp;&nbsp; System.out.println("student 无参数的构造函数");<br />}<br /><br />public Student(String name ,int age,String school)<br />{<br />&nbsp;&nbsp; System.out.println("student 3 参数的构造函数");<br />}<br />&nbsp;&nbsp;&nbsp; public&nbsp;&nbsp; Student(String name ,int age,String school,String grade)<br />{<br />&nbsp;&nbsp; super(name,age);<br />&nbsp;&nbsp; this.school=school;<br />&nbsp;&nbsp; this.grade=grade;<br />&nbsp;&nbsp; System.out.println("student 4 参数的构造函数，super().");<br />}<br />}</p>
<p>class Test<br />{<br />public static void main(String [] args)<br />{<br />&nbsp;&nbsp; System.out.println("st1:");<br />&nbsp;&nbsp; Student st2=new Student();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("---------------------------");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp; System.out.println("st2:");<br />&nbsp;&nbsp; Student st=new Student("zhangshan",76,"武大");<br />&nbsp;&nbsp; System.out.println("---------------------------");<br />&nbsp;&nbsp;<br />&nbsp;&nbsp; System.out.println("st3:");<br />&nbsp;&nbsp; Student st3=new Student("lisi",24,"武大","研究生");<br /><br />}<br />}&nbsp;</p>
<p>/*<br />=======================================<br />输出如下：<br /><br />E:JavaWork&gt;java Test<br />st1:<br />person无参数构造函数<br />student 无参数的构造函数<br />---------------------------<br />st2:<br />person无参数构造函数<br />student 3 参数的构造函数<br />---------------------------<br />st3:<br />person 2 参数的构造函数<br />student 4 参数的构造函数，super().</p>
<p>**************************************</p>
<p>&nbsp;&nbsp;&nbsp; 说明了创建一个子类的对象实例的时候，必先调用父类的无参数的构造函数（默认构造函数），假如父类有带参数的构造函数，那么系统将不会给它创建无参数的构造函数，这时，子类在实例化的时候，因为找不到父类的默认构造函数，编译器将会报错，但如果在子类的构造函数中指定用父类的带参数的构造函数的时候，或者在父类中加一个无参数的构造函数，就不会报错。</p>
<p>＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝</p>
<p>我们假设A是B的父类，B是A的子类。<br /><br /><span style="color: red">1、如果程序员没有给类A没有提供构造函数，则编译器会自动提供一个默认的无参数的构造函数，如果用户提供了自己的构造函数，则编译器就不在提供默认的无参数构造函数。</span><br /><br /><span style="color: red">2、子类B实例化时会自动调用父类A的默认构造函数，所以如果A的默认的无参数的构造函数为private，则编译器会报错，而如果A没有提供默认的无参数的构造函数，而提供了其他类型的构造函数，编译器同样会报错，因为B找不到A的默认无参数构造函数。所以，我们最好给父类A提供一个无参数的构造函数。</span></p>
<p><span style="color: red">3、或者在B的构造函数中显示的调用父类A的有参构造函数。super（parameter</span></p> <img src ="http://www.blogjava.net/jimingminlovefly/aggbug/374871.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jimingminlovefly/" target="_blank">计明敏</a> 2012-04-17 11:32 <a href="http://www.blogjava.net/jimingminlovefly/articles/374871.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>技术－socket通信编程（详解）</title><link>http://www.blogjava.net/jimingminlovefly/articles/366530.html</link><dc:creator>计明敏</dc:creator><author>计明敏</author><pubDate>Fri, 16 Dec 2011 06:54:00 GMT</pubDate><guid>http://www.blogjava.net/jimingminlovefly/articles/366530.html</guid><wfw:comment>http://www.blogjava.net/jimingminlovefly/comments/366530.html</wfw:comment><comments>http://www.blogjava.net/jimingminlovefly/articles/366530.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jimingminlovefly/comments/commentRss/366530.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jimingminlovefly/services/trackbacks/366530.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1. 客户端程序　　import java.io.*;　　import java.net.*;　　public class TalkClient {　　　　public static void main(String args[]) {　　　　　　try{　　　　　　　　Socket socket=new Socket("127.0.0.1",4700);　　　　　　　...&nbsp;&nbsp;<a href='http://www.blogjava.net/jimingminlovefly/articles/366530.html'>阅读全文</a><img src ="http://www.blogjava.net/jimingminlovefly/aggbug/366530.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jimingminlovefly/" target="_blank">计明敏</a> 2011-12-16 14:54 <a href="http://www.blogjava.net/jimingminlovefly/articles/366530.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>