﻿<?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>C++博客-天之道-随笔分类-Java</title><link>http://www.cppblog.com/zhenglinbo/category/20597.html</link><description>享受编程的乐趣。</description><language>zh-cn</language><lastBuildDate>Wed, 02 Oct 2013 12:42:13 GMT</lastBuildDate><pubDate>Wed, 02 Oct 2013 12:42:13 GMT</pubDate><ttl>60</ttl><item><title>浅谈Java内部类</title><link>http://www.cppblog.com/zhenglinbo/archive/2013/09/28/203473.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Sat, 28 Sep 2013 06:26:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2013/09/28/203473.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/203473.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2013/09/28/203473.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/203473.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/203473.html</trackback:ping><description><![CDATA[<br />什么是内部类呢？顾名思义，内部类就是在类中可以定义另一个的类。内部类是外部对象的一个成员，同样具有public , private 和 protected的访问权限。<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Test<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Family&nbsp;my&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Family(&#8220;Jonh",130);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my.getMsg();<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><span style="color: #0000FF; ">class</span>&nbsp;Family<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Family(String name,int weight){&nbsp;<span style="color: #0000FF; ">this</span>.f&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Father(name,weight);&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Father<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;weight;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;String&nbsp;name;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Father(String&nbsp;n,<span style="color: #0000FF; ">int</span>&nbsp;w)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.name&nbsp;=&nbsp;n;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.weight&nbsp;=&nbsp;w;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;getWeight()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;weight;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;String&nbsp;getName()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;name;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;Father&nbsp;f;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;getMsg()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Name:&nbsp;"+f.getName()+"\nWeight:&nbsp;"+f.getWeight());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><div></div><div>类Family 中有一个Father类，声明为private，表明在Family类中可以创建一个实例对象，这个Father专属于Family类。普通的（非内部）类不能声明为private或者protected，只能声明为public。因此这样的代码是不被允许的：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->Family.Father&nbsp;a&nbsp;=&nbsp;my.<span style="color: #0000FF; ">new</span>&nbsp;Father("Jonh",150);</div><br />如果要使用上述代码，只要修改内部类的访问权限就可以了，如去掉private权限，则默认为包访问权限，同一个包中的类都可以访问它，而不是只能从Family类才能访问。<br /><br /><div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;test<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Family&nbsp;my&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Family("Jonh",130);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my.getMsg();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Family.Father&nbsp;a&nbsp;=&nbsp;my.<span style="color: #0000FF; ">new</span>&nbsp;Father("Jonh",150);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Name:&nbsp;"+a.getName()+"\nWeight:&nbsp;"+a.getWeight());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div>在上述代码中，在创建内部类对象时，语法为：Family.Father a = my.new Father("Jonh",150); 说明内部类对象的创建是基于一个外部类对象（my），也就是说内部类对象必须依附于一个外部类对象。</div><br />内部类可以出现在所属类的方法内或任意作用域内。像下面的代码将内部类嵌入在方法内：<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;test<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Family&nbsp;my&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Family();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my.getMsg("Jonh",150);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><span style="color: #0000FF; ">class</span>&nbsp;Family<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Family(){&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;getMsg(String&nbsp;s,<span style="color: #0000FF; ">int</span>&nbsp;n)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Father<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;weight;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;String&nbsp;name;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Father(String&nbsp;n,<span style="color: #0000FF; ">int</span>&nbsp;w)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.name&nbsp;=&nbsp;n;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.weight&nbsp;=&nbsp;w;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;getWeight()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;weight;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;String&nbsp;getName()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;name;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Father&nbsp;f&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Father(s,n);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Name:&nbsp;"+f.getName()+"\nWeight:&nbsp;"+f.getWeight());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}</div><br /><br /><strong>闭包<br /></strong><br />内部类可以访问外部类的成员变量（即使是private），如在Family类中添加成员变量height，在Father类中定义一个方法 getHeight()，则能成功访问这个height变量，而在外部类中不能访问内部类中的成员变量。<br /><br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><br /><span style="color: #0000FF; ">class</span>&nbsp;Family<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;height&nbsp;=&nbsp;180;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">定义外部类属性height</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Family(String&nbsp;name,<span style="color: #0000FF; ">int</span>&nbsp;weight){&nbsp;<span style="color: #0000FF; ">this</span>.f&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Father(name,weight);&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Father<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;weight;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;String&nbsp;name;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Father(String&nbsp;n,<span style="color: #0000FF; ">int</span>&nbsp;w)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.name&nbsp;=&nbsp;n;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">this</span>.weight&nbsp;=&nbsp;w;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;getWeight()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;weight;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;String&nbsp;getName()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;name;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">int</span>&nbsp;getHeight()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">return</span>&nbsp;height;&nbsp;&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">访问外部类的属性height</span><span style="color: #008000; ">*/</span><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">private</span>&nbsp;Father&nbsp;f;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;getMsg()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Name:&nbsp;"+f.getName()+"\nWeight:&nbsp;"+f.getWeight()+"\nHeight:&nbsp;"+f.getHeight());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;test<br />{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args)<br />&nbsp;&nbsp;&nbsp;&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Family&nbsp;my&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Family("Jonh",130);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my.getMsg();<br />&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<span style="color: #008000;">/*</span><span style="color: #008000;">&nbsp;not&nbsp;allowed&nbsp;</span><span style="color: #008000;">*/</span><div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%; word-break: break-all;">&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">&nbsp;System.out.println(my.weight);&nbsp;</span><span style="color: #008000; ">*/</span></div>&nbsp; &nbsp; }<br />}</div><br />如果把内部类单独拿到外面来声明，那么要使用外部类的属性如height，就要先创建外部类的对象，再由对象调用其height属性，现在由于内部类处于外部类中，所以在程序调用时不必再创建外部类的对象，直接就可以使用height，这样减少了一部分内存空间的开销。<br /><br /><strong>嵌套static类</strong><br /><br />在类内部定义static类，称为嵌套static类。<br />我们可以直接创建嵌套类，而不必依赖于某个外部类对象。嵌套类无法调用外部对象的方法、也无法读取或修改外部对象的数据。<br />如：<br /><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Test{<br />&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;main(String[]&nbsp;args){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Father.Son&nbsp;John&nbsp;=&nbsp;<span style="color: #0000FF; ">new</span>&nbsp;Father.Son();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;John.display();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /><span style="color: #0000FF; ">class</span>&nbsp;Father{<br />&nbsp;&nbsp;<span style="color: #008000; ">/*</span><span style="color: #008000; ">嵌套类</span><span style="color: #008000; ">*/</span><br />&nbsp;<span style="color: #0000FF; ">static</span>&nbsp;<span style="color: #0000FF; ">class</span>&nbsp;Son{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000FF; ">public</span>&nbsp;<span style="color: #0000FF; ">void</span>&nbsp;display(){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("I&nbsp;am&nbsp;his&nbsp;son.");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />&nbsp;&nbsp;&nbsp;}<br />}</div><br /><strong>总结</strong><br />1. 内部类丰富了类的组织形式；<br />2. 内部类实现了闭包。<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><img src ="http://www.cppblog.com/zhenglinbo/aggbug/203473.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2013-09-28 14:26 <a href="http://www.cppblog.com/zhenglinbo/archive/2013/09/28/203473.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java对象引用（转）</title><link>http://www.cppblog.com/zhenglinbo/archive/2013/09/27/203450.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Fri, 27 Sep 2013 00:39:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2013/09/27/203450.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/203450.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2013/09/27/203450.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/203450.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/203450.html</trackback:ping><description><![CDATA[<div><span style="font-size: 12px;">作者：Vamei 出处：http://www.cnblogs.com/vamei 欢迎转载，也请保留这段声明。谢谢！</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">我们之前一直在使用&#8220;对象&#8221;这个概念，但没有探讨对象在内存中的具体存储方式。这方面的讨论将引出&#8220;对象引用&#8221;(object reference)这一重要概念。&nbsp;</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">对象引用</span></div><div><span style="font-size: 12px;">我们沿用之前定义的Human类，并有一个Test类:</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">复制代码</span></div><div><span style="font-size: 12px;">public class Test</span></div><div><span style="font-size: 12px;">{</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; public static void main(String[] args)</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; {</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; Human aPerson = new Human(160); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; }</span></div><div><span style="font-size: 12px;">}</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">class Human</span></div><div><span style="font-size: 12px;">{ &nbsp;&nbsp;</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; /**</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp;* constructor</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp;*/</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; public Human(int h)</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; {</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; this.height = h;</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; }</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; /**</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp;* accessor</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp;*/</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; public int getHeight()</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; {</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp;return this.height;</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; }</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; /**</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp;* mutator</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp;*/</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; public void growHeight(int h)</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; {</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; this.height = this.height + h;</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; }</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; private int height;</span></div><div><span style="font-size: 12px;">}</span></div><div><span style="font-size: 12px;">复制代码</span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">外部可以调用类来创建对象，比如上面在Test类中:</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">Human aPerson = new Human(160);</span></div><div><span style="font-size: 12px;">创建了一个Human类的对象aPerson。&nbsp;</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">上面是一个非常简单的表述，但我们有许多细节需要深入:</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">首先看等号的右侧。new是在内存中为对象开辟空间。具体来说，new是在内存的堆(heap)上为对象开辟空间。这一空间中，保存有对象的数据和方法。</span></div><div><span style="font-size: 12px;">再看等号的左侧。aPerson指代一个Human对象，被称为对象引用(reference)。实际上，aPerson并不是对象本身，而是类似于一个指向对象的指针。aPerson存在于内存的栈(stack)中。</span></div><div><span style="font-size: 12px;">当我们用等号赋值时，是将右侧new在堆中创建对象的地址赋予给对象引用。</span></div><div><span style="font-size: 12px;">这里的内存，指的是JVM (Java Virtual Machine)虚拟出来的Java进程内存空间。内存的堆和栈概念可参考Linux从程序到进程。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;<img src="http://www.cppblog.com/images/cppblog_com/zhenglinbo/31232316-9ceb14006ae34b97b3fbefaafccc9f80.png" border="0" alt="" width="211" height="274" /></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">对象引用</span></div><div><span style="font-size: 12px;"><br /></span></div><div></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">栈的读取速度比堆快，但栈上存储的数据受到有效范围的限制。在C语言中，当一次函数调用结束时，相应的栈帧(stack frame)要删除，栈帧上存储的参量和自动变量就消失了。Java的栈也受到同样的限制，当一次方法调用结束，该方法存储在栈上的数据将清空。在 Java中，所有的(普通)对象都储存在堆上。因此，new关键字的完整含义是，在堆上创建对象。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">基本类型(primitive type)的对象，比如int, double，保存在栈上。当我们声明基本类型时，不需要new。一旦声明，Java将在栈上直接存储基本类型的数据。所以，基本类型的变量名表示的是数据本身，不是引用。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">引用和对象的关系就像风筝和人。我们看天空时(程序里写的)，看到的是风筝(引用)，但风筝下面对应的，是人(对象):</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;"><img src="http://www.cppblog.com/images/cppblog_com/zhenglinbo/2.jpg" border="0" alt="" width="600" height="776" /><br /></span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">引用和对象分离；引用指向对象</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">尽管引用和对象是分离的，但我们所有通往对象的访问必须经过引用这个&#8220;大门&#8221;，比如以 引用.方法() 的方式访问对象的方法。在Java中，我们不能跳过引用去直接接触对象。再比如，对象a的数据成员如果是一个普通对象b，a的数据成员保存的是指向对象b的引用 (如果是基本类型变量，那么a的数据成员保存的是基本类型变量本身了)。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">在Java中，引用起到了指针的作用，但我们不能直接修改指针的值，比如像C语言那样将指针值加1。我们只能通过引用执行对对象的操作。这样的设计避免了许多指针可能引起的错误。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">引用的赋值</span></div><div><span style="font-size: 12px;">当我们将一个引用赋值给另一个引用时，我们实际上复制的是对象的地址。两个引用将指向同一对象。比如 dummyPerson=aPerson;，将导致:</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;"><img src="http://www.cppblog.com/images/cppblog_com/zhenglinbo/3.png" border="0" alt="" width="279" height="318" /><br /></span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">一个对象可以有多个引用 (一个人可以放多个风筝)。当程序通过某个引用修改对象时，通过其他引用也可以看到该修改。我们可以用以下Test类来测试实际效果:</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">复制代码</span></div><div><span style="font-size: 12px;">public class Test</span></div><div><span style="font-size: 12px;">{</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; public static void main(String[] args)</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; {</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Human aPerson = new Human(160);</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Human dummyPerson = aPerson;</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;System.out.println(dummyPerson.getHeight());</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;aPerson.growHeight(20);</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;System.out.println(dummyPerson.getHeight());</span></div><div><span style="font-size: 12px;">&nbsp; &nbsp; &nbsp; &nbsp; }</span></div><div><span style="font-size: 12px;">}</span></div><div><span style="font-size: 12px;">复制代码</span></div><div><span style="font-size: 12px;">我们对aPerson的修改将影响到dummyPerson。这两个引用实际上指向同一对象。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">所以，将一个引用赋值给另一个引用，并不能复制对象本身。我们必须寻求其他的机制来复制对象。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">垃圾回收</span></div><div><span style="font-size: 12px;">随着方法调用的结束，引用和基本类型变量会被清空。由于对象存活于堆，所以对象所占据的内存不会随着方法调用的结束而清空。进程空间可能很快被不断创建的对象占满。Java内建有垃圾回收(garbage collection)机制，用于清空不再使用的对象，以回收内存空间。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">垃圾回收的基本原则是，当存在引用指向某个对象时，那么该对象不会被回收; 当没有任何引用指向某个对象时，该对象被清空。它所占据的空间被回收。</span></div><div><span style="font-size: 12px;"><img src="http://www.cppblog.com/images/cppblog_com/zhenglinbo/4.png" border="0" alt="" width="307" height="464" /><br /></span></div><div><span style="font-size: 12px;">上图假设了某个时刻JVM中的内存状态。Human Object有三个引用: 来自栈的aPerson和dummyPerson，以及另一个对象的数据成员president。而Club Object没有引用。如果这个时候垃圾回收启动，那么Club Object将被清空，而Human Object来自Club Object的引用(president)也随之被删除。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">垃圾回收是Java中重要的机制，它直接影响了Java的运行效率。我将在以后深入其细节。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">参数传递<br /><br /></span></div><div><span style="font-size: 12px;">当我们分离了引用和对象的概念后，Java方法的参数传递机制实际上非常清晰: Java的参数传递为值传递。也就是说，当我们传递一个参数时，方法将获得该参数的一个拷贝。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">实际上，我们传递的参数，一个是基本类型的变量，另一个为对象的引用。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">基本类型变量的值传递，意味着变量本身被复制，并传递给Java方法。Java方法对变量的修改不会影响到原变量。</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">引用的值传递，意味着对象的地址被复制，并传递给Java方法。Java方法根据该引用的访问将会影响对象。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">在这里有另一个值得一提的情况: 我们在方法内部使用new创建对象，并将该对象的引用返回。如果该返回被一个引用接收，由于对象的引用不为0，对象依然存在，不会被垃圾回收。</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">总结</span></div><div><span style="font-size: 12px;">new</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">引用，对象</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">被垃圾回收的条件</span></div><div><span style="font-size: 12px;"><br /></span></div><div><span style="font-size: 12px;">参数: 值传递</span></div><div><span style="font-size: 12px;"><br /></span></div><div>&nbsp;</div><img src ="http://www.cppblog.com/zhenglinbo/aggbug/203450.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2013-09-27 08:39 <a href="http://www.cppblog.com/zhenglinbo/archive/2013/09/27/203450.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java socket编程入门（转）</title><link>http://www.cppblog.com/zhenglinbo/archive/2013/07/05/201533.html</link><dc:creator>hoshelly</dc:creator><author>hoshelly</author><pubDate>Fri, 05 Jul 2013 07:55:00 GMT</pubDate><guid>http://www.cppblog.com/zhenglinbo/archive/2013/07/05/201533.html</guid><wfw:comment>http://www.cppblog.com/zhenglinbo/comments/201533.html</wfw:comment><comments>http://www.cppblog.com/zhenglinbo/archive/2013/07/05/201533.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/zhenglinbo/comments/commentRss/201533.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/zhenglinbo/services/trackbacks/201533.html</trackback:ping><description><![CDATA[这个网站上讲得很清楚，就不转载了，直接贴地址：<span style="font-size: 12px;"><a href="http://www.binarytides.com/java-socket-programming-tutorial/">http://www.binarytides.com/java-socket-programming-tutorial/</a></span><img src ="http://www.cppblog.com/zhenglinbo/aggbug/201533.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/zhenglinbo/" target="_blank">hoshelly</a> 2013-07-05 15:55 <a href="http://www.cppblog.com/zhenglinbo/archive/2013/07/05/201533.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>