<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>翊天阁 Junsan 个人空间</title>
	<atom:link href="http://www.javastar.org/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.javastar.org</link>
	<description>技术管理之路</description>
	<lastBuildDate>Fri, 18 May 2012 14:52:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Eclipse(Myeclipse)中如何恢复已删除文件</title>
		<link>http://www.javastar.org/?p=320</link>
		<comments>http://www.javastar.org/?p=320#comments</comments>
		<pubDate>Wed, 16 May 2012 05:09:40 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[JAVA开发]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[myeclipse]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=320</guid>
		<description><![CDATA[Eclipse和MyEclipse都有删除文件恢复功能，当然如果你删除的时候按了shift键选择彻底那肯定无法恢复了，如果简单的使用了删除命令删除，那么Eclipse和MyEclipse会有一个历史文件缓存区，我们可以从这个区域恢复我们删除的文件。 操作很简单： 鼠标右键点击项目名，选择右键菜单靠下部分的Restore from Local history菜单，在弹出的对话框中，包含所有已经被删除的文件，选择你要恢复的文件恢复即可。 Eclipse和MyEclipse还有一个功能，就是恢复当前编辑文件的历史版本，操作起来也很简单，在文件的编辑区点右键，里面有个Local History的菜单，打开后会有文件保存的历史记录，当然不会是全部的，选择相应的历史记录恢复即可。]]></description>
			<content:encoded><![CDATA[<p>Eclipse和MyEclipse都有删除文件恢复功能，当然如果你删除的时候按了shift键选择彻底那肯定无法恢复了，如果简单的使用了删除命令删除，那么Eclipse和MyEclipse会有一个历史文件缓存区，我们可以从这个区域恢复我们删除的文件。</p>
<p>操作很简单：<br />
鼠标右键点击项目名，选择右键菜单靠下部分的Restore from Local history菜单，在弹出的对话框中，包含所有已经被删除的文件，选择你要恢复的文件恢复即可。<br />
<span id="more-320"></span><br />
Eclipse和MyEclipse还有一个功能，就是恢复当前编辑文件的历史版本，操作起来也很简单，在文件的编辑区点右键，里面有个Local History的菜单，打开后会有文件保存的历史记录，当然不会是全部的，选择相应的历史记录恢复即可。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=320</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>网站速度终于上来了</title>
		<link>http://www.javastar.org/?p=305</link>
		<comments>http://www.javastar.org/?p=305#comments</comments>
		<pubDate>Fri, 04 May 2012 17:10:44 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[业界新闻]]></category>
		<category><![CDATA[双线]]></category>
		<category><![CDATA[服务器]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=305</guid>
		<description><![CDATA[服务器原来托管在绍兴电信机房，基本上稍微有点网络距离的联通用户打开网站访问就非常的慢，经过跟托管商的协商，补了一些费用终于把服务器搬到了宁波BGP双线机房，现在的速度刷刷的。 服务器自己用不了，有需要空间的朋友可以联系我，价格低出售几份空间，价格400到850元/年不等，不收论坛、影视网站之类的内容无法控制的网站，最好企业网站，个人博客或者电子商务网站之类的。 联系QQ 334620162]]></description>
			<content:encoded><![CDATA[<p>服务器原来托管在绍兴电信机房，基本上稍微有点网络距离的联通用户打开网站访问就非常的慢，经过跟托管商的协商，补了一些费用终于把服务器搬到了宁波BGP双线机房，现在的速度刷刷的。</p>
<p>服务器自己用不了，有需要空间的朋友可以联系我，价格低出售几份空间，价格400到850元/年不等，不收论坛、影视网站之类的内容无法控制的网站，最好企业网站，个人博客或者电子商务网站之类的。</p>
<p>联系QQ 334620162</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=305</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eclipse快捷键大全</title>
		<link>http://www.javastar.org/?p=298</link>
		<comments>http://www.javastar.org/?p=298#comments</comments>
		<pubDate>Sat, 21 Apr 2012 14:47:42 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[JAVA开发]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[myeclipse]]></category>
		<category><![CDATA[快捷键]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=298</guid>
		<description><![CDATA[很有用的东西，平时用myeclipse，有了这个提高效率。 Ctrl+1 快速修复(最经典的快捷键,就不用多说了) Ctrl+D: 删除当前行 Ctrl+Alt+↓ 复制当前行到下一行(复制增加) Ctrl+Alt+↑ 复制当前行到上一行(复制增加) Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了) Alt+↑ 当前行和上面一行交互位置(同上) Alt+← 前一个编辑的页面 Alt+→ 下一个编辑的页面(当然是针对上面那条来说了) Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性 Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后) Shift+Ctrl+Enter 在当前行插入空行(原理同上条) Ctrl+Q 定位到最后编辑的地方 Ctrl+L 定位在某行 (对于程序超过100的人就有福音了) Ctrl+M 最大化当前的Edit或View (再按则反之) Ctrl+/ 注释当前行,再按则取消注释 Ctrl+O 快速显示 OutLine Ctrl+T 快速显示当前类的继承结构 Ctrl+W 关闭当前Editer Ctrl+K 参照选中的Word快速定位到下一个 Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示) Ctrl+/(小键盘) 折叠当前类中的所有代码 Ctrl+×(小键盘) 展开当前类中的所有代码 Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替) Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作) Ctrl+J [...]]]></description>
			<content:encoded><![CDATA[<p>很有用的东西，平时用myeclipse，有了这个提高效率。</p>
<p>Ctrl+1 快速修复(最经典的快捷键,就不用多说了)<br />
Ctrl+D: 删除当前行<br />
Ctrl+Alt+↓ 复制当前行到下一行(复制增加)<br />
Ctrl+Alt+↑ 复制当前行到上一行(复制增加)<br />
Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,再粘贴了)<br />
Alt+↑ 当前行和上面一行交互位置(同上)<br />
Alt+← 前一个编辑的页面<br />
Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)<br />
<span id="more-298"></span>Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性<br />
Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)<br />
Shift+Ctrl+Enter 在当前行插入空行(原理同上条)<br />
Ctrl+Q 定位到最后编辑的地方<br />
Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)<br />
Ctrl+M 最大化当前的Edit或View (再按则反之)<br />
Ctrl+/ 注释当前行,再按则取消注释<br />
Ctrl+O 快速显示 OutLine<br />
Ctrl+T 快速显示当前类的继承结构<br />
Ctrl+W 关闭当前Editer<br />
Ctrl+K 参照选中的Word快速定位到下一个<br />
Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)<br />
Ctrl+/(小键盘) 折叠当前类中的所有代码<br />
Ctrl+×(小键盘) 展开当前类中的所有代码<br />
Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)<br />
Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)<br />
Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)<br />
Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)<br />
Ctrl+Shift+F4 关闭所有打开的Editer<br />
Ctrl+Shift+X 把当前选中的文本全部变味小写<br />
Ctrl+Shift+Y 把当前选中的文本全部变为小写<br />
Ctrl+Shift+F 格式化当前代码<br />
Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)</p>
<p>下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift开头的了)<br />
Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)<br />
Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)<br />
Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)<br />
Alt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)<br />
Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)<br />
Alt+Shift+I 合并变量(可能这样说有点不妥Inline)<br />
Alt+Shift+V 移动函数和变量(不怎么常用)<br />
Alt+Shift+Z 重构的后悔药(Undo)</p>
<p>编辑<br />
作用域 功能 快捷键<br />
全局 查找并替换 Ctrl+F<br />
文本编辑器 查找上一个 Ctrl+Shift+K<br />
文本编辑器 查找下一个 Ctrl+K<br />
全局 撤销 Ctrl+Z<br />
全局 复制 Ctrl+C<br />
全局 恢复上一个选择 Alt+Shift+↓<br />
全局 剪切 Ctrl+X<br />
全局 快速修正 Ctrl1+1<br />
全局 内容辅助 Alt+/<br />
全局 全部选中 Ctrl+A<br />
全局 删除 Delete<br />
全局 上下文信息 Alt+？<br />
Alt+Shift+?<br />
Ctrl+Shift+Space<br />
Java编辑器 显示工具提示描述 F2<br />
Java编辑器 选择封装元素 Alt+Shift+↑<br />
Java编辑器 选择上一个元素 Alt+Shift+←<br />
Java编辑器 选择下一个元素 Alt+Shift+→<br />
文本编辑器 增量查找 Ctrl+J<br />
文本编辑器 增量逆向查找 Ctrl+Shift+J<br />
全局 粘贴 Ctrl+V<br />
全局 重做 Ctrl+Y</p>
<p>查看<br />
作用域 功能 快捷键<br />
全局 放大 Ctrl+=<br />
全局 缩小 Ctrl+-</p>
<p>窗口<br />
作用域 功能 快捷键<br />
全局 激活编辑器 F12<br />
全局 切换编辑器 Ctrl+Shift+W<br />
全局 上一个编辑器 Ctrl+Shift+F6<br />
全局 上一个视图 Ctrl+Shift+F7<br />
全局 上一个透视图 Ctrl+Shift+F8<br />
全局 下一个编辑器 Ctrl+F6<br />
全局 下一个视图 Ctrl+F7<br />
全局 下一个透视图 Ctrl+F8<br />
文本编辑器 显示标尺上下文菜单 Ctrl+W<br />
全局 显示视图菜单 Ctrl+F10<br />
全局 显示系统菜单 Alt+-</p>
<p>导航<br />
作用域 功能 快捷键<br />
Java编辑器 打开结构 Ctrl+F3<br />
全局 打开类型 Ctrl+Shift+T<br />
全局 打开类型层次结构 F4<br />
全局 打开声明 F3<br />
全局 打开外部javadoc Shift+F2<br />
全局 打开资源 Ctrl+Shift+R<br />
全局 后退历史记录 Alt+←<br />
全局 前进历史记录 Alt+→<br />
全局 上一个 Ctrl+,<br />
全局 下一个 Ctrl+.<br />
Java编辑器 显示大纲 Ctrl+O<br />
全局 在层次结构中打开类型 Ctrl+Shift+H<br />
全局 转至匹配的括号 Ctrl+Shift+P<br />
全局 转至上一个编辑位置 Ctrl+Q<br />
Java编辑器 转至上一个成员 Ctrl+Shift+↑<br />
Java编辑器 转至下一个成员 Ctrl+Shift+↓<br />
文本编辑器 转至行 Ctrl+L</p>
<p>搜索<br />
作用域 功能 快捷键<br />
全局 出现在文件中 Ctrl+Shift+U<br />
全局 打开搜索对话框 Ctrl+H<br />
全局 工作区中的声明 Ctrl+G<br />
全局 工作区中的引用 Ctrl+Shift+G</p>
<p>文本编辑<br />
作用域 功能 快捷键<br />
文本编辑器 改写切换 Insert<br />
文本编辑器 上滚行 Ctrl+↑<br />
文本编辑器 下滚行 Ctrl+↓</p>
<p>文件<br />
作用域 功能 快捷键<br />
全局 保存 Ctrl+X<br />
Ctrl+S<br />
全局 打印 Ctrl+P<br />
全局 关闭 Ctrl+F4<br />
全局 全部保存 Ctrl+Shift+S<br />
全局 全部关闭 Ctrl+Shift+F4<br />
全局 属性 Alt+Enter<br />
全局 新建 Ctrl+N</p>
<p>项目<br />
作用域 功能 快捷键<br />
全局 全部构建 Ctrl+B</p>
<p>源代码<br />
作用域 功能 快捷键<br />
Java编辑器 格式化 Ctrl+Shift+F<br />
Java编辑器 取消注释 Ctrl+\<br />
Java编辑器 注释 Ctrl+/<br />
Java编辑器 添加导入 Ctrl+Shift+M<br />
Java编辑器 组织导入 Ctrl+Shift+O<br />
Java编辑器 使用try/catch块来包围 未设置，太常用了，所以在这里列出,建议自己设置。<br />
也可以使用Ctrl+1自动修正。</p>
<p>运行<br />
作用域 功能 快捷键<br />
全局 单步返回 F7<br />
全局 单步跳过 F6<br />
全局 单步跳入 F5<br />
全局 单步跳入选择 Ctrl+F5<br />
全局 调试上次启动 F11<br />
全局 继续 F8<br />
全局 使用过滤器单步执行 Shift+F5<br />
全局 添加/去除断点 Ctrl+Shift+B<br />
全局 显示 Ctrl+D<br />
全局 运行上次启动 Ctrl+F11<br />
全局 运行至行 Ctrl+R<br />
全局 执行 Ctrl+U</p>
<p>重构<br />
作用域 功能 快捷键<br />
全局 撤销重构 Alt+Shift+Z<br />
全局 抽取方法 Alt+Shift+M<br />
全局 抽取局部变量 Alt+Shift+L<br />
全局 内联 Alt+Shift+I<br />
全局 移动 Alt+Shift+V<br />
全局 重命名 Alt+Shift+R<br />
全局 重做 Alt+Shift+Y</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=298</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java内部类总结(整理补充)</title>
		<link>http://www.javastar.org/?p=289</link>
		<comments>http://www.javastar.org/?p=289#comments</comments>
		<pubDate>Thu, 12 Apr 2012 05:14:33 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[JAVA开发]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[内部类]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=289</guid>
		<description><![CDATA[参考网上的内部类资料，自己总结了如下关于内部的特性，如果要学内部类是比较全的了。 1、java内部类的基本概念 内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员，并且依附于外部类而存在的。利用它可对那些逻辑上相互联系的类进行分组。 内部类可为静态，可用protected和private修饰（而外部类只能使用public和缺省的包访问权限），实现了控制一个类在另一个类里的“可见性”。 可以声明为abstract的供其他内部类或外部类继承与扩展，或者声明为static、final的，也可以实现特定的接口。 static的内部类行为上象一个独立的类，非static在行为上类似类的属性或方法且禁止声明static的方法。 内部类可以访问外部类的所有方法与属性，但static的内部类只能访问外部类的静态属性与方法。 2、为什么需要内部类？ 　　典型的情况是，内部类继承自某个类或实现某个接口，内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。使用内部类最吸引人的原因是： 　　每个内部类都能独立地继承自一个（接口的）实现，所以无论外围类是否已经继承了某个（接口的）实现，对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力，一些设计与编程问题就很难解决。从这个角度看，内部类使得多重继承的解决方案变得完整。接口解决了部分问题，而内部类有效地实现了“多重继承”。 3、外部类使用内部类的方法 内部类类似外部类的属性，因此访问内部类对象时总是需要一个创建好的外部类对象。 外部类按常规的类访问方式使用内部类，唯一的差别是外部类可以访问内部类的所有方法与属性，包括私有方法与属性。如：         Pinner p = new Pinner();         p.index = 20;         p.print();         &#8212;- 这种方式适合外部类的非static方法；         Pouter po = new Pouter();         Pinner pi = po.new Pinner();         pi.index = 40;         pi.Print();         &#8212;- 这种方式适合外部类的static方法； 如果需要在其他类中访问内部类，可以使用： (1)外部类提供创建内部类的方法供其他类使用。如：         // 外部类         [...]]]></description>
			<content:encoded><![CDATA[<p>参考网上的内部类资料，自己总结了如下关于内部的特性，如果要学内部类是比较全的了。</p>
<p>1、java内部类的基本概念</p>
<p>内部类是指在一个外部类的内部再定义一个类。内部类作为外部类的一个成员，并且依附于外部类而存在的。利用它可对那些逻辑上相互联系的类进行分组。</p>
<p>内部类可为静态，可用protected和private修饰（而外部类只能使用public和缺省的包访问权限），实现了控制一个类在另一个类里的“可见性”。</p>
<p>可以声明为abstract的供其他内部类或外部类继承与扩展，或者声明为static、final的，也可以实现特定的接口。</p>
<p><span id="more-289"></span>static的内部类行为上象一个独立的类，非static在行为上类似类的属性或方法且禁止声明static的方法。</p>
<p>内部类可以访问外部类的所有方法与属性，但static的内部类只能访问外部类的静态属性与方法。</p>
<p>2、为什么需要内部类？</p>
<p>　　典型的情况是，内部类继承自某个类或实现某个接口，内部类的代码操作创建其的外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。使用内部类最吸引人的原因是：</p>
<p>　　每个内部类都能独立地继承自一个（接口的）实现，所以无论外围类是否已经继承了某个（接口的）实现，对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力，一些设计与编程问题就很难解决。从这个角度看，内部类使得多重继承的解决方案变得完整。接口解决了部分问题，而内部类有效地实现了“多重继承”。</p>
<p>3、外部类使用内部类的方法</p>
<p>内部类类似外部类的属性，因此访问内部类对象时总是需要一个创建好的外部类对象。</p>
<p>外部类按常规的类访问方式使用内部类，唯一的差别是外部类可以访问内部类的所有方法与属性，包括私有方法与属性。如：<br />
        Pinner p = new Pinner();<br />
        p.index = 20;<br />
        p.print();<br />
        &#8212;- 这种方式适合外部类的非static方法；</p>
<p>        Pouter po = new Pouter();<br />
        Pinner pi = po.new Pinner();<br />
        pi.index = 40;<br />
        pi.Print();<br />
        &#8212;- 这种方式适合外部类的static方法；</p>
<p>如果需要在其他类中访问内部类，可以使用：<br />
(1)外部类提供创建内部类的方法供其他类使用。如：<br />
        // 外部类<br />
        Pinner getPinner()<br />
        {<br />
            return new Pinner();<br />
        }</p>
<p>        // 其他类<br />
        pouter.Pinner pi = po.getPinner();<br />
        pi.print();</p>
<p>(2)直接创建内部类的对象。如：<br />
        Pouter po = new Pouter();<br />
        Pouter.Pinner pi = po.new Pinner();<br />
        pi.print();</p>
<p>4、内部类主要有以下几类：成员内部类、局部内部类、静态内部类、匿名内部类</p>
<p>　　A：成员内部类</p>
<p>　　作为外部类的一个成员存在，与外部类的属性、方法并列。<br />
1.成员内部类必须利用外部类的实例创建<br />
2.成员内部类可以共享外部类的实例变量</p>
<p>成员内部类定义方法<br />
class OuterClass {<br />
    &#8230;<br />
    class NestedClass {<br />
        &#8230;<br />
    }<br />
}</p>
<p>例如：</p>
<p>public class Outer {<br />
 private static int i = 1;<br />
 private int j = 10;<br />
 private int k = 20;</p>
<p> public static void outer_f1() {<br />
  System.out.println(“outer_f1&#8243;);<br />
 }</p>
<p> public void outer_f2() {<br />
  System.out.println(“outer_f2&#8243;);<br />
 }</p>
<p> // 成员内部类中，不能定义静态成员<br />
 // 成员内部类中，可以访问外部类的所有成员<br />
 class Inner {<br />
  // static int inner_i = 100; //内部类中不允许定义静态变量<br />
  private int j = 100; // 内部类和外部类的实例变量可以共存<br />
  int inner_i = 1;</p>
<p>  void inner_f1() {<br />
   System.out.println(i);<br />
   // 在内部类中访问内部类自己的变量直接用变量名<br />
   System.out.println(j);<br />
   // 在内部类中访问内部类自己的变量也可以用this.变量名<br />
   System.out.println(this.j);<br />
   // 在内部类中访问外部类中与内部类同名的实例变量用外部类名.this.变量名<br />
   System.out.println(Outer.this.j);<br />
   // 如果内部类中没有与外部类同名的变量，则可以直接用变量名访问外部类变量<br />
   System.out.println(k);<br />
   outer_f1();<br />
   outer_f2();<br />
  }<br />
 }</p>
<p> // 外部类的非静态方法访问成员内部类<br />
 public void outer_f3() {<br />
  Inner inner = new Inner();<br />
  inner.inner_f1();</p>
<p>  System.out.println(inner.j);<br />
 }</p>
<p> // 外部类的静态方法访问成员内部类，与在外部类外部访问成员内部类一样<br />
 public static void outer_f4() {<br />
  // step1 建立外部类对象<br />
  Outer out = new Outer();<br />
  // step2 根据外部类对象建立内部类对象<br />
  Inner inner = out.new Inner();<br />
  // step3 访问内部类的方法<br />
  inner.inner_f1();</p>
<p>  System.out.println(inner.inner_i);<br />
 }</p>
<p> public static void main(String[] args) {<br />
  // outer_f4(); //该语句的输出结果和下面三条语句的输出结果一样<br />
  // System.out.println(“&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-”);<br />
  // 如果要直接创建内部类的对象，不能想当然地认为只需加上外围类Outer的名字，<br />
  // 就可以按照通常的样子生成内部类的对象，而是必须使用此外围类的一个对象来<br />
  // 创建其内部类的一个对象：<br />
  // Outer.Inner outin = new Outer.Inner();//编译不通过<br />
  // Outer.Inner outin = new Outer().new Inner();//正确<br />
  // 因此，除非你已经有了外围类的一个对象，否则不可能生成内部类的对象。因为此<br />
  // 内部类的对象会悄悄地链接到创建它的外围类的对象。如果你用的是静态的内部类，<br />
  // 那就不需要对其外围类对象的引用。<br />
   Outer out = new Outer();<br />
   Outer.Inner outin = out.new Inner();<br />
   outin.inner_f1();<br />
 }</p>
<p>}</p>
<p>　　注意：内部类是一个编译时的概念，一旦编译成功，就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。</p>
<p>如果一个类继承内部类，则创建该类的对象时需提供一个外部类的对象作为构造方法的参数。如：<br />
class Car<br />
{<br />
    class Wheel<br />
    {</p>
<p>    }<br />
}</p>
<p>class SuperWheel extends Car.Wheel<br />
{<br />
    SuperWheel(Car car)<br />
    {<br />
        car.super();<br />
    }</p>
<p>    public static void main(String [] args)<br />
    {<br />
        Car car = new Car();<br />
        SuperWheel wl = new SuperWheel(car);<br />
    }<br />
}</p>
<p>JAVA 内部类还有一个作用，那就是实现JAVA的多继承。JAVA本身是不允许多继承的，如果我们想一个类继承多个基类，就可以使用内部类。通过内部类分别继承一个基类，外部类创建内部类的对象，并使用内部类的方法，变相地实现了多继承。</p>
<p>//普通内部类的继承<br />
//手机 <br />
abstract class Mobile { <br />
    public abstract void call(); <br />
} <br />
 <br />
// MP3播放器 <br />
abstract class Mp3Palyer { <br />
    public abstract void play(); <br />
} <br />
 <br />
// 智能手机 <br />
class SmartPhone { <br />
    private Mobile mb = new SmartMobile(); <br />
    private Mp3Palyer mp3 = new PhoneMp3(); <br />
 <br />
    public Mobile getMobile() { <br />
        return mb; <br />
    } <br />
 <br />
    public Mp3Palyer getMp3() { <br />
        return mp3; <br />
    } <br />
 <br />
    public class SmartMobile extends Mobile { <br />
        @Override <br />
        // 不同的智能机有的call方式 <br />
        public void call() { <br />
            System.out.println(“Call phone!”); <br />
        } <br />
    } <br />
 <br />
    public class PhoneMp3 extends Mp3Palyer { <br />
        @Override <br />
        // 不同的智能机有的play方式 <br />
        public void play() { <br />
            System.out.println(“Play music!”); <br />
        } <br />
    } <br />
} <br />
 <br />
public class MutiImpTest1 { <br />
    static void call(Mobile m) { <br />
        m.call(); <br />
    } <br />
 <br />
    static void play(Mp3Palyer p) { <br />
        p.play(); <br />
    } <br />
 <br />
    public static void main(String[] args) { <br />
        SmartPhone sp = new SmartPhone(); <br />
        call(sp.getMobile());// 智能手机具有手机功能 <br />
        play(sp.getMp3());// 又具有Mp3的功能 <br />
    } <br />
}</p>
<p>//匿名内部类的继承<br />
abstract class A {<br />
    abstract void methodA();<br />
}<br />
 <br />
abstract class B {<br />
    abstract void methodB();<br />
}<br />
 <br />
class C extends A {<br />
    @Override<br />
    void methodA() {<br />
       System.out.println(“extends A&#8217;s method”);<br />
    }<br />
 <br />
    B getB() {<br />
       return new B() {<br />
           @Override<br />
           void methodB() {<br />
              System.out.println(“extends B&#8217;s method”);<br />
           }<br />
       };<br />
    }<br />
}<br />
 <br />
public class MultiImplementation {<br />
    public void doA(A a) {<br />
       a.methodA();<br />
    }<br />
 <br />
    public void doB(B b) {<br />
       b.methodB();<br />
    }<br />
 <br />
    public static void main(String[] args) {<br />
       MultiImplementation mi = new MultiImplementation();<br />
       C c = new C();<br />
       mi.doA(c);<br />
       mi.doB(c.getB());<br />
    }<br />
}</p>
<p>//使用内部类实现了迭代模式<br />
public class DataStructure {<br />
    // create an array<br />
    private final static int SIZE = 15;<br />
    private int[] arrayOfInts = new int[SIZE];<br />
   <br />
    public DataStructure() {<br />
        // fill the array with ascending integer values<br />
        for (int i = 0; i &lt; SIZE; i++) {<br />
            arrayOfInts[i] = i;<br />
        }<br />
    }<br />
   <br />
    public void printEven() {<br />
        // print out values of even indices of the array<br />
        InnerEvenIterator iterator = this.new InnerEvenIterator();<br />
        while (iterator.hasNext()) {<br />
            System.out.println(iterator.getNext() + ” “);<br />
        }<br />
    }<br />
   <br />
    // inner class implements the Iterator pattern<br />
    private class InnerEvenIterator {<br />
        // start stepping through the array from the beginning<br />
        private int next = 0;<br />
       <br />
        public boolean hasNext() {<br />
            // check if a current element is the last in the array<br />
            return (next &lt;= SIZE &#8211; 1);<br />
        }<br />
       <br />
        public int getNext() {<br />
            // record a value of an even index of the array<br />
            int retValue = arrayOfInts[next];<br />
            //get the next even element<br />
            next += 2;<br />
            return retValue;<br />
        }<br />
    }<br />
   <br />
    public static void main(String s[]) {<br />
        // fill the array with integer values and print out only<br />
        // values of even indices<br />
        DataStructure ds = new DataStructure();<br />
        ds.printEven();<br />
    }<br />
}</p>
<p>　　B:局部内部类(第五次课)</p>
<p>　　内部类只在外围类中某个代码块中创建并使用，这种情况可以定义局部类。如在方法中定义的内部类。与局部变量类似，局部内部类不能有访问说明符如public或private等等，因为它不是外围类的一部分，但是它可以访问当前代码块内的常量，和此外围类所有的成员。</p>
<p>局部类的优势：1.对外部世界可以完全地隐藏起来。除了所在代码块之外，没有任何方法知道局部类的存在。<br />
              2.不仅能够访问包含它的外围类的成员，而且还可以访问局部变量(必须声明为final)。<br />
限制：1、局部内部类，只能在定义该内部类的局部代码块内实例化，不可以在此代码块外进行实例化。<br />
 2、局部内部类对象不能使用该类所在方法块的非final局部变量。因为方法的局部变量位于栈上，只存在与该方法的生命周期内，当一个方法结束，其栈结构被删除，局部变量成为历史。但是此时局部类对象可能没有被GC回收，仍然存在于堆中。例如，如果它的引用被传递到其他某些代码，并存在一个成员变量内。正因为不能保证局部变量和局部内部类的生命周期一样长，所以局部内部类不能使用他们。</p>
<p>例如：</p>
<p>public class OuterLocal {<br />
 private int s = 100;<br />
 private int out_i = 1;</p>
<p> public void f(final int k) {<br />
  final int s = 200;<br />
  int i = 1;<br />
  final int j = 10;</p>
<p>  // 定义在方法内部<br />
  class Inner {<br />
   int s = 300; // 可以定义与外部类同名的变量</p>
<p>   int inner_i = 100;</p>
<p>   // static int m = 20; //不可以定义静态变量<br />
   Inner(int h) {<br />
    inner_f(h);<br />
   }</p>
<p>   void inner_f(int h) {<br />
    // 如果内部类没有与外部类同名的变量，在内部类中可以直接访问外部类的实例变量<br />
    System.out.println(out_i);<br />
    // 可以访问外部类的局部变量(即方法内的变量)，但是变量必须是final的<br />
    System.out.println(j);<br />
    // System.out.println(i);<br />
    // 如果内部类中有与外部类同名的变量，直接用变量名访问的是内部类的变量<br />
    System.out.println(s);<br />
    // 用this.变量名访问的也是内部类变量<br />
    System.out.println(this.s);<br />
    // 用外部类名.this.内部类变量名访问的是外部类变量<br />
    System.out.println(OuterLocal.this.s);<br />
    //使用常量参数k<br />
    System.out.println(k);<br />
    System.out.println(h);<br />
   }<br />
  }<br />
  new Inner(k);//只能在方法内实例化<br />
 }</p>
<p> public static void main(String[] args) {<br />
  // 访问局部内部类必须先有外部类对象<br />
  OuterLocal out = new OuterLocal();<br />
  out.f(3);<br />
 }<br />
}<br />
　　C：静态内部类(嵌套类)：（注意：前两种内部类与变量类似，所以可以对照参考变量）(第六次课)</p>
<p>　　如果你不需要内部类对象与其外围类对象之间有联系，只是为了把一个类隐藏在另外一个类内部，那你可以将内部类声明为static。这通常称为嵌套类（nested class）。想要理解static应用于内部类时的含义，你就必须记住，普通的内部类对象隐含地保存了一个引用，指向创建它的外围类对象。然而，当内部类是static的时，就不是这样了。嵌套类意味着：</p>
<p>　　1. 要创建嵌套类的对象，并不需要其外围类的对象。<br />
　　2. 不能从嵌套类的对象中访问非静态的外围类对象。</p>
<p>静态内部类的定义：<br />
class OuterClass {<br />
    &#8230;<br />
    static class StaticNestedClass {<br />
        &#8230;<br />
    }<br />
    class InnerClass {<br />
        &#8230;<br />
    }<br />
}</p>
<p>注意：声明在接口中的内部类自动成为static和public。</p>
<p>OuterClass.StaticNestedClass nestedObject =<br />
     new OuterClass.StaticNestedClass();</p>
<p>public class OuterStatic {<br />
 private static int i = 1;<br />
 private int j = 10;</p>
<p> public static void outer_f1() {<br />
 }</p>
<p> public void outer_f2() {  <br />
 }</p>
<p> // 静态内部类可以用public,protected,private修饰<br />
 // 静态内部类中可以定义静态或者非静态的成员<br />
 static class Inner {<br />
  static int inner_i = 100;<br />
  int inner_j = 200;</p>
<p>  static void inner_f1() {<br />
   // 静态内部类只能访问外部类的静态成员(包括静态变量和静态方法)<br />
   System.out.println(“OuterStatic.i” + i);<br />
   outer_f1();<br />
  }</p>
<p>  void inner_f2() {<br />
   // 静态内部类不能访问外部类的非静态成员(包括非静态变量和非静态方法)<br />
   // System.out.println(“OuterStatic.j”+j);<br />
   // outer_f2();<br />
  }<br />
 }</p>
<p> public void outer_f3() {<br />
  // 外部类访问内部类的静态成员：内部类.静态成员<br />
  System.out.println(Inner.inner_i);<br />
  Inner.inner_f1();<br />
  // 外部类访问内部类的非静态成员:实例化内部类即可<br />
  Inner inner = new Inner();<br />
  inner.inner_f2();<br />
 }</p>
<p> public static void main(String[] args) {<br />
  new OuterStatic().outer_f3();<br />
 }<br />
}</p>
<p>　　生成一个静态内部类不需要外部类成员：这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成：Outer.Inner in = new Outer.Inner(); 而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类(正常情况下，你不能在接口内部放置任何代码，但嵌套类可以作为接口的一部分，因为它是static 的。只是将嵌套类置于接口的命名空间内，这并不违反接口的规则）</p>
<p>&nbsp;</p>
<p>　　D：匿名内部类(from thinking in java 3th)(第六次课)</p>
<p>　　简单地说：匿名内部类就是没有名字的内部类。</p>
<p>什么情况下需要使用匿名内部类？</p>
<p>如果满足下面的一些条件，使用匿名内部类是比较合适的：</p>
<p>　　·只用到类的一个实例。<br />
　　·类在定义后马上用到。<br />
　　·类非常小（SUN推荐是在4行代码以下）<br />
　　·给类命名并不会导致你的代码更容易被理解。</p>
<p>在使用匿名内部类时，要记住以下几个原则：<br />
　　·匿名内部类不能有构造方法。<br />
　　·匿名内部类不能定义任何静态成员、方法和类。<br />
　　·匿名内部类不能是public,protected,private,static。<br />
　　·只能创建匿名内部类的一个实例。<br />
    ·一个匿名内部类一定是在new的后面，用其隐含实现一个接口或实现一个类。<br />
　　·因匿名内部类为局部内部类，所以局部内部类的所有限制都对其生效。</p>
<p>比如使用内部类实现接口的功能(如事件处理器、适配器等)，而功能的差异较大，需要根据实际的情况创建相应的内部类时，可以使用匿名内部类。简单的示例如下：</p>
<p>&nbsp;</p>
<p>1.接口实现匿名内部类：<br />
interface WebView<br />
{<br />
    void doGet();<br />
}</p>
<p>class A<br />
{<br />
    WebView ShowName()<br />
    {<br />
        return new WebView()<br />
        {<br />
            void doGet()<br />
            {<br />
                System.out.println(“Name”);<br />
            }   <br />
        };<br />
    }</p>
<p>    WebView ShowCode()<br />
    {<br />
        return new WebView()<br />
        {<br />
            void doGet()<br />
            {<br />
                System.out.println(“Code”);<br />
            }   <br />
        };<br />
    }<br />
}<br />
2.对象创建匿名内部类<br />
下面的例子看起来有点奇怪，通过匿名内部类返回一个对象：</p>
<p>//接口<br />
public interface Contents {<br />
}</p>
<p>//在方法中返回一个匿名内部类<br />
public class Parcel6 {<br />
 public Contents cont() {<br />
  return new Contents() {<br />
   private int i = 11;</p>
<p>   public int value() {<br />
    return i;<br />
   }<br />
  }; // 在这里需要一个分号<br />
 }</p>
<p> public static void main(String[] args) {<br />
  Parcel6 p = new Parcel6();<br />
  Contents c = p.cont();<br />
 }<br />
}</p>
<p>　　cont()方法将下面两个动作合并在一起：返回值的生成，与表示这个返回值的类的定义！进一步说，这个类是匿名的，它没有名字。更糟的是，看起来是你正要创建一个Contents对象：</p>
<p>return new Contents()</p>
<p>　　但是，在到达语句结束的分号之前，你却说：“等一等，我想在这里插入一个类的定义”:</p>
<p>return new Contents() {<br />
private int i = 11;<br />
public int value() { return i; }<br />
};</p>
<p>　　这种奇怪的语法指的是：“创建一个继承自Contents的匿名类的对象。”通过new 表达式返回的引用被自动向上转型为对Contents的引用。匿名内部类的语法是下面例子的简略形式：</p>
<p>class MyContents implements Contents {<br />
private int i = 11;<br />
public int value() { return i; }<br />
}<br />
return new MyContents();</p>
<p>　　在这个匿名内部类中，使用了缺省的构造器来生成Contents。<br />
一个问题，怎么样才能在Contents的实例对象中使用value()方法？在接口中增加该方法的定义即可。</p>
<p>&nbsp;</p>
<p>3.父类继承匿名内部类<br />
下面的代码展示的是，如果你的基类需要一个有参数的构造器，应该怎么办：</p>
<p>public abstract class Wrapping {<br />
 private int x;<br />
 <br />
 public Wrapping(int x) {<br />
  this.x = x;<br />
 }<br />
 <br />
 public int value(){<br />
  return x;<br />
 }<br />
 <br />
 abstract int overideValue();<br />
}<br />
public class Parcel7 {<br />
 public Wrapping wrap(int x) {<br />
  // Base constructor call:<br />
  return new Wrapping(x) { // Pass constructor argument.<br />
   public int overideValue() {<br />
    return super.value() * 47;<br />
   }<br />
  }; // Semicolon required<br />
 }</p>
<p> public static void main(String[] args) {<br />
  Parcel7 p = new Parcel7();<br />
  Wrapping w = p.wrap(10);<br />
 }<br />
}</p>
<p>　　只需简单地传递合适的参数给基类的构造器即可，这里是将x 传进new Wrapping(x)。在匿名内部类末尾的分号，并不是用来标记此内部类结束（C++中是那样）。实际上，它标记的是表达式的结束，只不过这个表达式正巧包含了内部类罢了。因此，这与别的地方使用的分号是一致的。</p>
<p>&nbsp;</p>
<p>4.匿名内部类成员变量定义<br />
　　如果在匿名类中定义成员变量，你同样能够对其执行初始化操作：</p>
<p>public interface Destination {<br />
}</p>
<p>public class Parcel8 {<br />
 // Argument must be final to use inside<br />
 // anonymous inner class:<br />
 public Destination dest(final String dest) {<br />
  return new Destination() {<br />
   private String label = dest;</p>
<p>   public String readLabel() {<br />
    return label;<br />
   }<br />
  };<br />
 }</p>
<p> public static void main(String[] args) {<br />
  Parcel8 p = new Parcel8();<br />
  Destination d = p.dest(“Tanzania”);<br />
 }<br />
}</p>
<p>　　如果你有一个匿名内部类，它要使用一个在它的外部定义的对象，编译器会要求其参数引用是final 型的，就像dest()中的参数。如果你忘记了，会得到一个编译期错误信息。如果只是简单地给一个成员变量赋值，那么此例中的方法就可以了。</p>
<p>&nbsp;</p>
<p>5、匿名内部类构造器<br />
但是，如果你想做一些类似构造器的行为，该怎么办呢？在匿名类中不可能有已命名的构造器（因为它根本没名字！），但通过实例初始化，你就能够达到为匿名内部类“制作”一个构造器的效果。像这样做：</p>
<p>public abstract class Base {<br />
 public Base(int i) {<br />
  System.out.println(“Base constructor, i = ” + i);<br />
 }</p>
<p> public abstract void f();<br />
}</p>
<p>public class AnonymousConstructor {<br />
 public static Base getBase(int i) {<br />
  return new Base(i) {<br />
   {<br />
    System.out.println(“Inside instance initializer”);<br />
   }</p>
<p>   public void f() {<br />
    System.out.println(“In anonymous f()”);<br />
   }<br />
  };<br />
 }</p>
<p> public static void main(String[] args) {<br />
  Base base = getBase(47);<br />
  base.f();<br />
 }<br />
}</p>
<p>　　在此例中，不要求变量i 一定是final 的。因为i 被传递给匿名类的基类的构造器，它并不会在匿名类内部被直接使用。</p>
<p>6.匿名内部类中实例初始化<br />
下例是带实例初始化的“parcel”形式。注意dest()的参数必须是final，因为它们是在匿名类内被使用的。</p>
<p>public class Parcel9 {<br />
 public Destination dest(final String dest, final float price) {<br />
  return new Destination() {<br />
   private int cost;<br />
   // Instance initialization for each object:<br />
   {<br />
    cost = Math.round(price);<br />
    if (cost &gt; 100)<br />
     System.out.println(“Over budget!”);<br />
   }</p>
<p>   private String label = dest;</p>
<p>   public String readLabel() {<br />
    return label;<br />
   }<br />
  };<br />
 }</p>
<p> public static void main(String[] args) {<br />
  Parcel9 p = new Parcel9();<br />
  Destination d = p.dest(“Tanzania”, 101.395F);<br />
 }<br />
}</p>
<p>　　在实例初始化的部分，你可以看到有一段代码，那原本是不能作为成员变量初始化的一部分而执行的（就是if 语句）。所以对于匿名类而言，实例初始化的实际效果就是构造器。当然它受到了限制：你不能重载实例初始化，所以你只能有一个构造器。</p>
<p> <br />
5、从多层嵌套类中访问外部</p>
<p>　　一个内部类被嵌套多少层并不重要，它能透明地访问所有它所嵌入的外围类的所有成员，如下所示：</p>
<p>public class MNA {<br />
 private void f() {<br />
 }</p>
<p> class A {<br />
  private void g() {<br />
  }</p>
<p>  public class B {<br />
   void h() {<br />
    g();<br />
    f();<br />
   }<br />
  }<br />
 }<br />
}<br />
public class MultiNestingAccess {<br />
 public static void main(String[] args) {<br />
  MNA mna = new MNA();<br />
  MNA.A mnaa = mna.new A();<br />
  MNA.A.B mnaab = mnaa.new B();<br />
  mnaab.h();<br />
 }<br />
}</p>
<p>　　可以看到在MNA.A.B中，调用方法g()和f()不需要任何条件（即使它们被定义为private）。这个例子同时展示了如何从不同的类里面创建多层嵌套的内部类对象的基本语法。“.new”语法能产生正确的作用域，所以你不必在调用构造器时限定类名。<br />
6、内部类的重载问题</p>
<p>　　如果你创建了一个内部类，然后继承其外围类并重新定义此内部类时，会发生什么呢？也就是说，内部类可以被重载吗？这看起来似乎是个很有用的点子，但是“重载”内部类就好像它是外围类的一个方法，其实并不起什么作用：</p>
<p>public class Egg {<br />
 private Yolk y;</p>
<p> protected class Yolk {<br />
  public Yolk() {<br />
   System.out.println(“Egg.Yolk()”);<br />
  }<br />
 }</p>
<p> public Egg() {<br />
  System.out.println(“New Egg()”);<br />
  y = new Yolk();<br />
 }<br />
}</p>
<p>package cn.com.rsky.innerclass;</p>
<p>public class BigEgg extends Egg{<br />
 public class Yolk {<br />
  public Yolk() {<br />
   System.out.println(“BigEgg.Yolk()”);<br />
  }<br />
 }</p>
<p> public static void main(String[] args) {<br />
  new BigEgg().new Yolk();<br />
 }<br />
}<br />
　　输出结果为：</p>
<p>New Egg()<br />
Egg.Yolk()<br />
BigEgg.Yolk()<br />
　　缺省的构造器是编译器自动生成的，这里是调用基类的缺省构造器。你可能认为既然创建了BigEgg 的对象，那么所使用的应该是被“重载”过的Yolk，但你可以从输出中看到实际情况并不是这样的。</p>
<p>　　这个例子说明，当你继承了某个外围类的时候，内部类并没有发生什么特别神奇的变化。这两个内部类是完全独立的两个实体，各自在自己的命名空间内。</p>
<p>7、明确继承内部类<br />
当然，明确地继承某个内部类也是可以的：</p>
<p>public class Egg2 {<br />
 protected class Yolk {<br />
  public Yolk() {<br />
   System.out.println(“Egg2.Yolk()”);<br />
  }</p>
<p>  public void f() {<br />
   System.out.println(“Egg2.Yolk.f()”);<br />
  }<br />
 }</p>
<p> private Yolk y = new Yolk();</p>
<p> public Egg2() {<br />
  System.out.println(“New Egg2()”);<br />
 }</p>
<p> public void insertYolk(Yolk yy) {<br />
  y = yy;<br />
 }</p>
<p> public void g() {<br />
  y.f();<br />
 }<br />
}</p>
<p>public class BigEgg2 extends Egg2 {<br />
 public class Yolk extends Egg2.Yolk {<br />
  public Yolk() {<br />
   System.out.println(“BigEgg2.Yolk()”);<br />
  }</p>
<p>  public void f() {<br />
   System.out.println(“BigEgg2.Yolk.f()”);<br />
  }<br />
 }</p>
<p> public BigEgg2() {<br />
  insertYolk(new Yolk());<br />
 }</p>
<p> public static void main(String[] args) {<br />
  Egg2 e2 = new BigEgg2();<br />
  e2.g();<br />
 }<br />
}</p>
<p>　　输出结果为：</p>
<p>Egg2.Yolk()<br />
New Egg2()<br />
Egg2.Yolk()<br />
BigEgg2.Yolk()<br />
BigEgg2.Yolk.f()</p>
<p>　　现在BigEgg2.Yolk 通过extends Egg2.Yolk 明确地继承了此内部类，并且重载了其中的方法。Egg2 的insertYolk()方法使得BigEgg2 将它自己的Yolk 对象向上转型，然后传递给引用y。所以当g()调用y.f()时，重载后的新版的f()被执行。第二次调用Egg2.Yolk()是BigEgg2.Yolk 的构造器调用了其基类的构造器。可以看到在调用g()的时候，新版的f()被调用了。</p>
<p>如果看不懂，可以使用单步调试的方法，来看具体的运行和输出结果。</p>
<p>8、外部类对内部类的继承问题（thinking in java 3th p294）</p>
<p>　　因为内部类的构造器要用到其外围类对象的引用，所以在你继承一个内部类的时候，事情变得有点复杂。问题在于，那个“秘密的”外围类对象的引用必须被初始化，而在被继承的类中并不存在要联接的缺省对象。要解决这个问题，需使用专门的语法来明确说清它们之间的关联：</p>
<p>public class WithInner {<br />
 class Inner {<br />
  Inner() {<br />
   System.out.println(“this is a constructor in WithInner.Inner”);<br />
  };<br />
 }<br />
}</p>
<p>public class InheritInner extends WithInner.Inner {<br />
 // ! InheritInner() {} // Won&#8217;t compile<br />
 InheritInner(WithInner wi) {<br />
  wi.super();<br />
  System.out.println(“this is a constructor in InheritInner”);<br />
 }</p>
<p> public static void main(String[] args) {<br />
  WithInner wi = new WithInner();<br />
  InheritInner ii = new InheritInner(wi);<br />
 }<br />
}</p>
<p>　　输出结果为：</p>
<p>this is a constructor in WithInner.Inner<br />
this is a constructor in InheritInner</p>
<p>　　可以看到，InheritInner 只继承自内部类，而不是外围类。但是当要生成一个构造器时，缺省的构造器并不算好，而且你不能只是传递一个指向外围类对象的引用。此外，你必须在构造器内使用如下语法：</p>
<p>enclosingClassReference.super();</p>
<p>　　这样才提供了必要的引用，然后程序才能编译通过。<br />
匿名内部类在swing中的例子：</p>
<p>import javax.swing.*;<br />
import java.awt.event.*;</p>
<p>public class Test {<br />
 JButton b;<br />
 JRadioButton rb;</p>
<p> public Test() {<br />
  JFrame f = new JFrame(“Test”);<br />
  f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
  f.getContentPane().setLayout(new java.awt.FlowLayout());<br />
  b = new JButton(“JButton”);<br />
  rb = new JRadioButton(“RadioButton”);<br />
  ActionListener a = new ActionListener() {<br />
   public void actionPerformed(ActionEvent ae) {<br />
    if (ae.getSource() == b) {<br />
     System.out.println(“You clicked the JButton”);<br />
    } else {<br />
     System.out.println(“You clicked the RadioButton”);<br />
    }<br />
   }<br />
  };<br />
  b.addActionListener(a);<br />
  rb.addActionListener(a);<br />
  f.getContentPane().add(b);<br />
  f.getContentPane().add(rb);<br />
  f.pack();<br />
  f.show();<br />
 }</p>
<p> public static void main(String[] args) {<br />
  new Test();<br />
 }<br />
}</p>
<p>&nbsp;</p>
<p>import java.awt.event.ActionEvent;<br />
import java.awt.event.ActionListener;<br />
import java.awt.event.ItemEvent;<br />
import java.awt.event.ItemListener;<br />
import javax.swing.ButtonGroup;<br />
import javax.swing.JButton;<br />
import javax.swing.JCheckBox;<br />
import javax.swing.JFrame;<br />
import javax.swing.JLabel;<br />
import javax.swing.JRadioButton;<br />
import javax.swing.JToggleButton;</p>
<p>public final class TestButtons {<br />
 public static void main(String[] args) {<br />
  TestButtons tb = new TestButtons();<br />
  tb.show();<br />
 }</p>
<p> JFrame frame = new JFrame(“Test Buttons”);<br />
 JButton jButton = new JButton(“JButton”);<br />
 // 按钮<br />
 JToggleButton toggle = new JToggleButton(“Toggle Button”);<br />
 // 切换按钮<br />
 JCheckBox checkBox = new JCheckBox(“Check Box”);<br />
 // 复选按钮<br />
 JRadioButton radio1 = new JRadioButton(“Radio Button 1&#8243;);<br />
 // 单选按钮<br />
 JRadioButton radio2 = new JRadioButton(“Radio Button 2&#8243;);<br />
 JRadioButton radio3 = new JRadioButton(“Radio Button 3&#8243;);<br />
 JLabel label = new JLabel(“Here is Status, look here.”);</p>
<p> // 不是按钮，是静态文本<br />
 public TestButtons() {<br />
  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);<br />
  frame.getContentPane().setLayout(new java.awt.FlowLayout());<br />
  // 为一般按钮添加动作监听器<br />
  jButton.addActionListener(new ActionListener() {<br />
   public void actionPerformed(ActionEvent ae) {<br />
    label.setText(“You clicked jButton”);<br />
   }<br />
  });<br />
  // 为切换按钮添加动作监听器<br />
  toggle.addActionListener(new ActionListener() {<br />
   public void actionPerformed(ActionEvent ae) {<br />
    JToggleButton toggle = (JToggleButton) ae.getSource();<br />
    if (toggle.isSelected()) {<br />
     label.setText(“You selected Toggle Button”);<br />
    } else {<br />
     label.setText(“You deselected Toggle Button”);<br />
    }<br />
   }<br />
  });<br />
  // 为复选按钮添加条目监听器<br />
  checkBox.addItemListener(new ItemListener() {<br />
   public void itemStateChanged(ItemEvent e) {<br />
    JCheckBox cb = (JCheckBox) e.getSource();<br />
    label.setText(“Selected Check Box is ” + cb.isSelected());<br />
   }<br />
  });<br />
  // 用一个按钮组对象包容一组单选按钮<br />
  ButtonGroup group = new ButtonGroup();<br />
  // 生成一个新的动作监听器对象，备用<br />
  ActionListener al = new ActionListener() {<br />
   public void actionPerformed(ActionEvent ae) {<br />
    JRadioButton radio = (JRadioButton) ae.getSource();<br />
    if (radio == radio1) {<br />
     label.setText(“You selected Radio Button 1&#8243;);<br />
    } else if (radio == radio2) {<br />
     label.setText(“You selected Radio Button 2&#8243;);<br />
    } else {<br />
     label.setText(“You selected Radio Button 3&#8243;);<br />
    }<br />
   }<br />
  };<br />
  // 为各单选按钮添加动作监听器<br />
  radio1.addActionListener(al);<br />
  radio2.addActionListener(al);<br />
  radio3.addActionListener(al);<br />
  // 将单选按钮添加到按钮组中<br />
  group.add(radio1);<br />
  group.add(radio2);<br />
  group.add(radio3);<br />
  frame.getContentPane().add(jButton);<br />
  frame.getContentPane().add(toggle);<br />
  frame.getContentPane().add(checkBox);<br />
  frame.getContentPane().add(radio1);<br />
  frame.getContentPane().add(radio2);<br />
  frame.getContentPane().add(radio3);<br />
  frame.getContentPane().add(label);<br />
  frame.setSize(200, 250);<br />
 }</p>
<p> public void show() {<br />
  frame.setVisible(true);<br />
 }<br />
}</p>
<p>&nbsp;</p>
<p>public class TestFrame extends JFrame {<br />
 private int counter = 0;</p>
<p> public TestFrame() {<br />
  /* 使用匿名类添加一个窗口监听器 */<br />
  addWindowListener(new WindowAdapter() {<br />
   public void windowClosing(WindowEvent e) {<br />
    System.out.println(“Exit when Closed event”);<br />
    // 退出应用程序<br />
    System.exit(0);<br />
   }</p>
<p>   public void windowActivated(WindowEvent e) {<br />
    // 改变窗口标题<br />
    setTitle(“Test Frame ” + counter++);<br />
   }<br />
  });<br />
  // 设置窗口为固定大小<br />
  setResizable(false);<br />
  setSize(200, 150);<br />
 }</p>
<p> public static void main(String[] args) {<br />
  TestFrame tf = new TestFrame();<br />
  tf.show();<br />
 }<br />
}<br />
import java.awt.BorderLayout;<br />
import javax.swing.JButton;<br />
import javax.swing.JFrame;<br />
import javax.swing.JPanel;<br />
import javax.swing.JScrollPane;<br />
import javax.swing.JTextArea;</p>
<p>public final class TestPanels extends JFrame {<br />
 public static void main(String[] args) {<br />
  TestPanels tp = new TestPanels();<br />
  tp.setVisible(true);<br />
 }</p>
<p> public TestPanels() {<br />
  setDefaultCloseOperation(EXIT_ON_CLOSE);<br />
  JPanel panel = new JPanel();<br />
  for (int i = 0; i &lt; 2; i++) {<br />
   panel.add(new JButton(“Button 00&#8243; + i));<br />
  }<br />
  JTextArea textArea = new JTextArea(5, 15);<br />
  textArea.setLineWrap(true);<br />
  JScrollPane scrollPane = new JScrollPane(textArea);<br />
  getContentPane().add(panel, BorderLayout.NORTH);<br />
  getContentPane().add(scrollPane, BorderLayout.CENTER);<br />
  pack();<br />
 }<br />
}</p>
<p>&nbsp;</p>
<p>import javax.swing.JFrame;<br />
import javax.swing.JLabel;<br />
import javax.swing.JPasswordField;<br />
import javax.swing.JTextArea;<br />
import javax.swing.JTextField;<br />
import javax.swing.event.CaretEvent;<br />
import javax.swing.event.CaretListener;</p>
<p>public final class TestTexts extends JFrame {<br />
 public static void main(String[] args) {<br />
  TestTexts tt = new TestTexts();<br />
  tt.setVisible(true);<br />
 }</p>
<p> private JLabel label = new JLabel(“Status”);<br />
 private JTextField textField;<br />
 private JPasswordField pwdField;<br />
 private JTextArea textArea;</p>
<p> public TestTexts() {<br />
  super(“Test Texts”);<br />
  setDefaultCloseOperation(EXIT_ON_CLOSE);<br />
  getContentPane().setLayout(new java.awt.FlowLayout());<br />
  textField = new JTextField(15);<br />
  /* 监听文本光标移动事件 */<br />
  textField.addCaretListener(new CaretListener() {<br />
   public void caretUpdate(CaretEvent e) {<br />
    // 如果改变了内容，就可以即时更新 label 显示的内容<br />
    label.setText(textField.getText());<br />
   }<br />
  });<br />
  pwdField = new JPasswordField(15);<br />
  pwdField.setEchoChar(&#8216;#&#8217;);<br />
  textArea = new JTextArea(5, 15);<br />
  textArea.setLineWrap(true);<br />
  getContentPane().add(textField);<br />
  getContentPane().add(pwdField);<br />
  getContentPane().add(textArea);<br />
  getContentPane().add(label);<br />
  setSize(200, 200);<br />
 }<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=289</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java.policy 安全管理概念:代码证书签名和安全设置 的使用方法</title>
		<link>http://www.javastar.org/?p=277</link>
		<comments>http://www.javastar.org/?p=277#comments</comments>
		<pubDate>Fri, 06 Apr 2012 02:12:04 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[JAVA开发]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[policy]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[安全策略]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=277</guid>
		<description><![CDATA[本文讲解使用代码签名的方式，保证java代码执行安全的范例。 安全管理器让java代码访问外部资源的时候受到一层过滤。就像classloader和class文件检验器是检测java文件一样，从2个方面保证了代码的安全性。 在Java应用中，安全管理器是由System类中的方法setSecurityManager设置的。要获得当前的安全管理器，可以使用方法getSecurityManager。 java.lang.SecurityManager类包含了很多checkXXXX方法，如用于判断对文件访问权限的checkRead(String file)方法。这些检查方法调用SecurityManager.checkPermission方法，后者根据安全策略文件判断调用应用是否有执行所 请求的操作权限。如果没有，将引发SecurityException。 如果想让应用使用安全管理器和安全策略，可在启动JVM时设定 -Djava.security.manager选项，还可以同时指定安全策略文件。如果在应用中启用了Java安全管理器，却没有指定安全策略文件，那 么Java安全管理器将使用默认的安全策略，它们是由位于目录$JAVA_HOME/jre/lib/security中的java.policy定义 的。 概念 策略(Policy) 类装载器用Policy对象帮助它们决定，把一段代码导入虚拟机时应该给它们什么样的权限. 任何时候，每一个应用程序都只有一个Policy对象. 策略文件 Sun的java平台具体的Policy子类采用在一ASCII策略文件中用上下文无关文法描述安全策略. 一个策略文件包括了一系列grant子句，每一个grant子句将一些权限授给一个代码来源。 保护域(ProtectionDomain) 当类装载器将类型装入java虚拟机时，它们将为每一个类型指派一个保护域，保护域定义了授予 一段特定的代码的所有权限.装载入java虚拟机的每一个类型都属于一个且仅属于一个保护域. 访问控制器(AccessController) implies() 判断一个Permissioin对象的权限，是否隐含(imply)在另一个Permissioin对象的权限中。 checkPermission() AccessController的核心方法，这个方法决定一个特定的操作能否被允许. 它自顶向下检查栈，只要它遇到一个没有权限桢，它将抛出一个AccessControlException导常。 doPrivileged() 有的时候，调用栈较上层(更靠近栈顶)的代码可能希望执行一段代码，而这段代码在调用栈的较 下层是不允许执行的。 为了使可信的代码执行较不可靠的代码操作(这段不可靠的代码位于调用栈的较下层且没有执行 这个操作的权限),AccessController类重载了四个名为doPrivileged()的静态方法. AccessController会忽略调用doPrivileged()方法的调用者的调用者的权限. Permission: 权限是用抽象类java.security.Permission的一个子类的实例表示的. CodeSource: 代码来源，包含代码库URL和签名者. Permissions: PermissionCollection(权限集合)的子类 装载时生成保护域的步骤: 1           根据指定的Policy文件生成一个Policy对象 2           生成CodeSource 3           用CodeSource在Policy中找到CodeSource对应的Permissions 4           用CodeSource和Permissons构造一个ProtectionDomain 5           把ProtectionDomain同这个类在方法区中的类数据联系起来(ClassLoader.defineClass()). 以上简介了java.policy框架的基本结构和概念，下面通过一个实例来说明怎么使用证书对代码签名进行保护。 代码签名方式： 1.将待签名的class文件及**$1.class文件打成jar包 2.用jdk的keytool工具生成一对密钥： keytool -genkey [...]]]></description>
			<content:encoded><![CDATA[<p>本文讲解使用代码签名的方式，保证java代码执行安全的范例。</p>
<p>安全管理器让java代码访问外部资源的时候受到一层过滤。就像classloader和class文件检验器是检测java文件一样，从2个方面保证了代码的安全性。</p>
<p>在Java应用中，安全管理器是由System类中的方法setSecurityManager设置的。要获得当前的安全管理器，可以使用方法getSecurityManager。 <span id="more-277"></span></p>
<p>java.lang.SecurityManager类包含了很多checkXXXX方法，如用于判断对文件访问权限的checkRead(String file)方法。这些检查方法调用SecurityManager.checkPermission方法，后者根据安全策略文件判断调用应用是否有执行所 请求的操作权限。如果没有，将引发SecurityException。</p>
<p>如果想让应用使用安全管理器和安全策略，可在启动JVM时设定 -Djava.security.manager选项，还可以同时指定安全策略文件。如果在应用中启用了Java安全管理器，却没有指定安全策略文件，那 么Java安全管理器将使用默认的安全策略，它们是由位于目录$JAVA_HOME/jre/lib/security中的java.policy定义 的。</p>
<p>概念<br />
策略(Policy)<br />
类装载器用Policy对象帮助它们决定，把一段代码导入虚拟机时应该给它们什么样的权限. 任何时候，每一个应用程序都只有一个Policy对象.<br />
策略文件<br />
Sun的java平台具体的Policy子类采用在一ASCII策略文件中用上下文无关文法描述安全策略.<br />
一个策略文件包括了一系列grant子句，每一个grant子句将一些权限授给一个代码来源。<br />
保护域(ProtectionDomain)<br />
当类装载器将类型装入java虚拟机时，它们将为每一个类型指派一个保护域，保护域定义了授予<br />
一段特定的代码的所有权限.装载入java虚拟机的每一个类型都属于一个且仅属于一个保护域.<br />
访问控制器(AccessController)<br />
implies()<br />
判断一个Permissioin对象的权限，是否隐含(imply)在另一个Permissioin对象的权限中。<br />
checkPermission()<br />
AccessController的核心方法，这个方法决定一个特定的操作能否被允许.<br />
它自顶向下检查栈，只要它遇到一个没有权限桢，它将抛出一个AccessControlException导常。<br />
doPrivileged()<br />
有的时候，调用栈较上层(更靠近栈顶)的代码可能希望执行一段代码，而这段代码在调用栈的较<br />
下层是不允许执行的。<br />
为了使可信的代码执行较不可靠的代码操作(这段不可靠的代码位于调用栈的较下层且没有执行<br />
这个操作的权限),AccessController类重载了四个名为doPrivileged()的静态方法.<br />
AccessController会忽略调用doPrivileged()方法的调用者的调用者的权限.<br />
Permission:<br />
权限是用抽象类java.security.Permission的一个子类的实例表示的.<br />
CodeSource:<br />
代码来源，包含代码库URL和签名者.<br />
Permissions:<br />
PermissionCollection(权限集合)的子类</p>
<p>装载时生成保护域的步骤:<br />
1           根据指定的Policy文件生成一个Policy对象<br />
2           生成CodeSource<br />
3           用CodeSource在Policy中找到CodeSource对应的Permissions<br />
4           用CodeSource和Permissons构造一个ProtectionDomain<br />
5           把ProtectionDomain同这个类在方法区中的类数据联系起来(ClassLoader.defineClass()).</p>
<p>以上简介了java.policy框架的基本结构和概念，下面通过一个实例来说明怎么使用证书对代码签名进行保护。</p>
<p>代码签名方式：</p>
<p>1.将待签名的class文件及**$1.class文件打成jar包</p>
<p>2.用jdk的keytool工具生成一对密钥：</p>
<p>keytool -genkey -alias  密钥别名 -keypass 密钥密码 -validity 密钥有效天数 -keystore 密钥文件名</p>
<p>3.用jdk的jarsinger工具和第二步生成的密钥对jar包数字签名：</p>
<p>jarsinger -keystore  密钥文件名 -storepass  签名密码 -keypass 密钥密码   jar文件名  代码签名者姓名</p>
<p>这样代码签名就完成了</p>
<p>&nbsp;</p>
<p>在策略文件中 首先要加入密钥文件：keystore  “密钥文件名”;</p>
<p>grant signedBy 代码签名者姓名{ permission ****};</p>
<p>&nbsp;</p>
<p>在程序中要手动加载安全管理器：</p>
<p>System.setProperty(“java.security.policy”, “策略文件”);<br />
System.setSecurityManager(new SecurityManager());</p>
<p>这样在执行动作时就会先进行权限检查，阻止恶意代码进行非法操作</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=277</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java.policy策略详解</title>
		<link>http://www.javastar.org/?p=273</link>
		<comments>http://www.javastar.org/?p=273#comments</comments>
		<pubDate>Fri, 06 Apr 2012 01:22:18 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[JAVA开发]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[policy]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=273</guid>
		<description><![CDATA[Java语言的安全性及其完善的安全框架，大家都已经众所周知了。从编程语言，编译器、解释程序到Java虚拟机，都能确保Java系统不被无效的代码或敌对的编译器暗中破坏，基本上， 它们保证了Java代码按预定的规则运作。但是，当我们需要逾越这些限制时，例如，读写文件，监听和读写Socket，退出Java系统等，就必须使用数 字签名或安全策略文件（*.Policy）。 下面我们详细讲解java.policy的概念和使用方法。 一、Java中安全策略的概念 Java应用程序环境的安全策略，详细说明了对于不同的代码所拥有的不同资源的许可，它由一个 Policy对象来表达。为了让applet（或者运行在 SecurityManager下的一个应用程序）能够执行受保护的行为，例如读写文件，applet（或 Java应用程序）必须获得那项操作的许可,安全策略文件就是用来实现这些许可。 Policy对象可能有多个实体，虽然任何时候只能有一个起作用。当前安装的Policy对象，在程序中可以通过调用getPolicy方法得到，也可以 通过调用setPolicy方法改变。Policy对象评估整个策略，返回一个适当的Permissions对象，详细说明哪些代码可以访问哪些资源。 策略文件可以储存在无格式的ASCII文件或Policy类的二进制文件或数据库中。本文仅讨论无格式的ASCII文件的形式。 二、Policy文件的格式 为了能够更好地理解下面的内容，建议在阅读时参照 jdk/jre/lib/security/java.policy文件和jdk/jre/lib/security/java.security文件的内容。 Policy文件的语法格式与说明 一个Policy文件实质上是一个记录列表，它可能含有一个 “keystore”记录，以及含有零个或多个“grant”记录。其格式如下： keystore “some_keystore_url”, “keystore_type”; grant [ SignedBy “signer_names" ] [ , CodeBase “URL" ] { Permission permission_class_name [ “target_name" ] [ , “action"] [, SignedBy “signer_names" ]; Permission &#8230; }; (1)“keystore”记录 一个keystore是一个私有密钥（private keys）数据库和相应的数字签名，例如X.509证书。Policy文件中可能只有一条keystore记录（也可能不含有该记录），它可以出现在文件 中grant记录以外的任何地方。Policy配置文件中指定的 keystores用于寻找grant记录中指定的、签名者的公共密钥（public keys），如果任何grant 记录指定签名者（signer_names），那么，keystore记录必须出现在policy配置文件中。 “some_keystore_url” [...]]]></description>
			<content:encoded><![CDATA[<p>Java语言的安全性及其完善的安全框架，大家都已经众所周知了。从编程语言，编译器、解释程序到Java虚拟机，都能确保Java系统不被无效的代码或敌对的编译器暗中破坏，基本上， 它们保证了Java代码按预定的规则运作。但是，当我们需要逾越这些限制时，例如，读写文件，监听和读写Socket，退出Java系统等，就必须使用数 字签名或安全策略文件（*.Policy）。</p>
<p><span id="more-273"></span>下面我们详细讲解java.policy的概念和使用方法。</p>
<div id="cnblogs_post_body">
<p>一、Java中安全策略的概念<br />
Java应用程序环境的安全策略，详细说明了对于不同的代码所拥有的不同资源的许可，它由一个 Policy对象来表达。为了让applet（或者运行在 SecurityManager下的一个应用程序）能够执行受保护的行为，例如读写文件，applet（或 Java应用程序）必须获得那项操作的许可,安全策略文件就是用来实现这些许可。<br />
Policy对象可能有多个实体，虽然任何时候只能有一个起作用。当前安装的Policy对象，在程序中可以通过调用getPolicy方法得到，也可以 通过调用setPolicy方法改变。Policy对象评估整个策略，返回一个适当的Permissions对象，详细说明哪些代码可以访问哪些资源。</p>
<p>策略文件可以储存在无格式的ASCII文件或Policy类的二进制文件或数据库中。本文仅讨论无格式的ASCII文件的形式。</p>
<p>二、Policy文件的格式<br />
为了能够更好地理解下面的内容，建议在阅读时参照 jdk/jre/lib/security/java.policy文件和jdk/jre/lib/security/java.security文件的内容。<br />
Policy文件的语法格式与说明</p>
<p>一个Policy文件实质上是一个记录列表，它可能含有一个 “keystore”记录，以及含有零个或多个“grant”记录。其格式如下：</p>
<p>keystore “some_keystore_url”, “keystore_type”;</p>
<p>grant [ SignedBy “signer_names" ] [ , CodeBase “URL" ] {<br />
Permission permission_class_name [ “target_name" ]<br />
[ , “action"] [, SignedBy “signer_names" ];<br />
Permission &#8230;<br />
};</p>
<p>(1)“keystore”记录</p>
<p>一个keystore是一个私有密钥（private keys）数据库和相应的数字签名，例如X.509证书。Policy文件中可能只有一条keystore记录（也可能不含有该记录），它可以出现在文件 中grant记录以外的任何地方。Policy配置文件中指定的 keystores用于寻找grant记录中指定的、签名者的公共密钥（public keys），如果任何grant 记录指定签名者（signer_names），那么，keystore记录必须出现在policy配置文件中。</p>
<p>“some_keystore_url” 是指keystore的URL位置， “keystore_type”是指keystore的类型。第二个选项是可选项，如果没有指定，该类型则假定由安全属性文件 （java.security）中的“keystore.type”属性来确定。keystore类型定义了 keystore信息的存储和数据格式，用于保护keystore中的私有密钥和keystore完整性的算法。 Sun Microsystems支持的缺省类型为“JKS”。</p>
<p>(2)“grant”记录</p>
<p>在Policy文件中的每一个grant记录含有一个CodeSource （一个指定的代码）及其permission(许可)。</p>
<p>Policy 文件中的每一条grant记录遵循下面的格式，以保留字“grant”开头，表示一条新的记录的开始，“Permission”是另一个保留字，在记录中 用来标记一个新的许可的开始。每一个grant记录授予一个指定的代码（CodeBase）、一套许可（Permissions）。</p>
<p>permission_class_name必须是一个合格并存在的类名，例如java.io.FilePermission，不能使用缩写（例如，FilePermission）。</p>
<p>target_name用来指定目标类的位置，action用于指定目标类拥有的权限。</p>
<p>target_name可以直接指定类名（可以是绝对或相对路径）、目录名，也可以是下面的通配符：</p>
<p>directory/＊ 目录下的所有文件<br />
＊ 当前目录的所有文件<br />
directory/－ 目录下的所有文件，包括子目录<br />
－ 当前目录下的所有文件，包括子目录<br />
&lt;&lt; ALL FILES &gt;&gt;文件系统中的所有文件</p>
<p>对于java.io.FilePermission，action可以是：read, write, delete和execute。</p>
<p>对于java.net.SocketPermission，action可以是：listen， accept，connect，read，write。</p>
<p>(3)Policy文件中的属性扩展（Property Expansion）属性扩展与shell中使用的变量扩展类似，它的格式为：“＄{some.property}”</p>
<p>实际使用的例子为：<br />
permission java.io.FilePermission<br />
“＄{user.home}”, “read”;</p>
<p>“＄{user.home}”的值为“d:Project”，因此，下面的语句和上面的语句是一样的：permission java.io.FilePermission “d:Project “, “read”;</p>
<p>三、实 例<br />
当初始化Policy时，首先装载系统Policy，然后再增加用户Policy，如果两者都不存在，则使用缺省的Policy，即原始的沙箱模型。<br />
系统Policy文件的缺省位置为：<br />
{java.home}/lib/security/java.policy (Solaris)<br />
{java.home}libsecurityjava.policy (Windows)</p>
<p>用户Policy文件的缺省位置为：<br />
{user.home}/.java.policy (Solaris)<br />
{user.home}.java.policy (Windows)</p>
<p>其实，在实际使用中，我们可能不会像上面介绍的那么复杂，特别是在不使用数字签名时。这时，我们完全可以借鉴JDK 1.2提供给我们的现成的 jdk1.2jrelibsecurityjava.policy文件，根据我们的需要做相应的修改，本文就针对不使用数字签名情况详细说明安全策略文件 的用法。</p>
<p>下面，是一个完整的在Windows下使用的.java.policy文件。在文件中，分别使用注释的形式说明了每个“permission”记录的用途。</p>
<p>// For LanServerTalk.java and LanClientTalk.java</p>
<p>grant {<br />
//对系统和用户目录“读”的权限</p>
<p>permission java.util.PropertyPermission “user.dir”, “read”;<br />
permission java.util.PropertyPermission “user.home”, “read”;<br />
permission java.util.PropertyPermission “java.home”, “read”;<br />
permission java.util.PropertyPermission “java.class.path”, “read”;<br />
permission java.util.PropertyPermission “user.name”, “read”;</p>
<p>//对线程和线程组的操作权限<br />
permission java.lang.RuntimePermission “modifyThread”;<br />
permission java.lang.RuntimePermission “modifyThreadGroup”;</p>
<p>//操作Socket端口的各种权限<br />
permission java.net.SocketPermission “－”, “listen”;<br />
permission java.net.SocketPermission “－”, “accept”;<br />
permission java.net.SocketPermission “－”, “connect”;<br />
permission java.net.SocketPermission “－”, “read”;<br />
permission java.net.SocketPermission “－”, “write”;</p>
<p>//读写文件的权限<br />
permission java.io.FilePermission “－”, “read”;<br />
permission java.io.FilePermission “－”, “write”;</p>
<p>//退出系统的权限，例如System.exit(0)<br />
permission java.lang.RuntimePermission “exitVM”;<br />
};</p>
<p>四、.Java.policy文件的使用<br />
对于Windows 95/98/NT，使用.Java.policy文件的方法主要有下面两种。<br />
1． 使用缺省目录</p>
<p>我们可以简单地将编辑好的.Java.policy文件拷贝到 Windows 95/98/NT的HOME目录，这时，所有的applet(或Java应用程序)可能都拥有某些相同的权限，使用起来简单，但不灵活（例如：对于 Java.io.FilePermission ，其目标类的 target_name必须使用绝对路径），如果不是在企业内部网中使用，还可能存在一定安全隐患。</p>
<p>2． 在命令行中指定</p>
<p>在命令行，如果我们希望传递一个Policy文件给 appletviewer，还可以使用“－J－Djava.security.policy”参数来指定policy的位置：</p>
<p>appletviewer －J－Djava.security.policy=pURL myApplet</p>
<p>pURL为Policy文件的位置。下面，是一个实际的例子，以当前目录的.java.policy文件所指定的安全策略运行当前目录的LanServerTalk.html（文件中装载并运行LanServerTalk.Java）：</p>
<p>appletviewer －J－Djava.security.policy=.Java.policy LanServerTalk.html</p>
<p>这种方法使用灵活，特别是作为一个软件包在企业内部网中发布时，安装、设置和迁移软件，基本无须修改Policy文件的内容，使用起来相当简单，而且，安全许可的范围控制较精细</p>
<p>grant {<br />
permission java.security.AllPermission;<br />
};</p>
<p>一点特别的补充：</p>
<p>The exact meaning of a codeBase value depends on the characters at the end. A codeBase with a trailing “/”</p>
<p>matches all class files (not JAR files) in the specified directory. A codeBase with a trailing “/*” matches</p>
<p>all files (both class and JAR files) contained in that directory. A codeBase with a trailing “/-” matches</p>
<p>all files (both class and JAR files) in the directory and recursively all files in subdirectories contained</p>
<p>in that directory. The following table illustrates the different cases.</p>
<p>/    表示所有的class文件(不包括Jar，不包括子目录）</p>
<p>/*   表示所有的class文件(包括Jar，不包括子目录）</p>
<p>/-   表示所有的class文件(包括Jar，包括子目录）</p>
<p>Policy文件中的属性扩展（Property Expansion）</p>
<p>属性扩展与shell中使用的变量扩展类似，它的格式为：</p>
<p>permission java.io.FilePermission</p>
<p>“${user.home}”, “read”;</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=273</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java培训通知(2012年5月16日更新)</title>
		<link>http://www.javastar.org/?p=271</link>
		<comments>http://www.javastar.org/?p=271#comments</comments>
		<pubDate>Thu, 29 Mar 2012 04:49:58 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[JAVA开发]]></category>
		<category><![CDATA[业界新闻]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[培训]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=271</guid>
		<description><![CDATA[近期我们将开始举行java培训，前期免费，主要是从浅入深的讲解java基础知识，常用框架，如spring，struts，hibernate，mybatis等等。 有兴趣的同学可以访问这里 http://bbs.rsky.com.cn/forum.php?mod=forumdisplay&#038;fid=135 了解详情。 咨询QQ 334620162 附录： 培训地点： java群 4885880  主要是授课内容文字和例程 YY语音 19799748 启天培训社区  语音实时讲解 交流群 启天社区Java超级群 177587205 培训时间，每次课90~120分钟左右。 课程上课时间即时通知请入群 4885880 课程安排： 2012年3月31日 晚19:30  java基础第一课 java介绍和开发环境搭建 2012年4月10日 晚20:00  java基础第二课 java的基本语法一(变量、表达式、运算符、控制语句、数组) 2012年4月12日 晚20:30  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授了包、类、方法和访问控制 2012年4月13日 晚20:30  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授了常量、变量、静态变量和final关键字 2012年4月15日 晚20:00  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授了接口、枚举 2012年4月17日 晚20:30  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授注解 、注释和成员内部类 2012年4月19日 晚20:30  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授局部内部类、静态内部类和匿名内部类 2012年4月20日 晚20:20  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授静态内部类和匿名内部类 2012年4月22日 晚20:20 java基础第四课 java中面向对象概念(封装、继承、多态、抽象方法、泛型、反射) 讲授封装、继承和抽象方法 2012年4月24日 晚20:20 java基础第四课 java中面向对象概念(封装、继承、多态、抽象方法、泛型、反射) 讲授多态、泛型和反射 [...]]]></description>
			<content:encoded><![CDATA[<p>近期我们将开始举行java培训，前期免费，主要是从浅入深的讲解java基础知识，常用框架，如spring，struts，hibernate，mybatis等等。</p>
<p>有兴趣的同学可以访问这里</p>
<p>http://bbs.rsky.com.cn/forum.php?mod=forumdisplay&#038;fid=135</p>
<p>了解详情。</p>
<p>咨询QQ 334620162</p>
<p><span id="more-271"></span>附录：</p>
<p>培训地点：<br />
java群 4885880  主要是授课内容文字和例程<br />
YY语音 19799748 启天培训社区  语音实时讲解<br />
交流群 启天社区Java超级群 177587205</p>
<p>培训时间，每次课90~120分钟左右。</p>
<p>课程上课时间即时通知请入群 4885880</p>
<p>课程安排：</p>
<p>2012年3月31日 晚19:30  java基础第一课 java介绍和开发环境搭建</p>
<p>2012年4月10日 晚20:00  java基础第二课 java的基本语法一(变量、表达式、运算符、控制语句、数组)</p>
<p>2012年4月12日 晚20:30  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授了包、类、方法和访问控制</p>
<p>2012年4月13日 晚20:30  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授了常量、变量、静态变量和final关键字</p>
<p>2012年4月15日 晚20:00  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授了接口、枚举</p>
<p>2012年4月17日 晚20:30  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授注解 、注释和成员内部类</p>
<p>2012年4月19日 晚20:30  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授局部内部类、静态内部类和匿名内部类</p>
<p>2012年4月20日 晚20:20  java基础第三课 java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解)  讲授静态内部类和匿名内部类</p>
<p>2012年4月22日 晚20:20 java基础第四课 java中面向对象概念(封装、继承、多态、抽象方法、泛型、反射) 讲授封装、继承和抽象方法</p>
<p>2012年4月24日 晚20:20 java基础第四课 java中面向对象概念(封装、继承、多态、抽象方法、泛型、反射) 讲授多态、泛型和反射</p>
<p>2012年4月25日 晚20:20 第五课 java常用类及其方法(String/StringBuffer，StringBuilder，Collection及其子类[集合类]、Vector 及其子类、System等) 讲授System、Runtime、String、StringBuffer、StringBuilder、StringTokenizer、 Properties等类</p>
<p>2012年4月26日 晚20:20 第五课 java常用类及其方法(String/StringBuffer，StringBuilder，Collection及其子类[集合类]、Vector及其子类、System等) 讲授集合类、日期类、正则表达式</p>
<p>2012年5月8日 晚20:20 第六课 java的JVM及垃圾回收器 讲授java虚拟机的生命周期、jvm的体系结构:类加载系统、执行引擎、本地方法接口</p>
<p>2012年5月9日  晚20:20 第六课 java的JVM及垃圾回收器 讲授jvm的体系结构内存区：方法区、堆、栈、程序计数器、运行时常量池、本地方法栈及垃圾回收器</p>
<p>2012年5月11日 晚20:30 第七课 java异常处理和安全(异常、调试和断言)</p>
<p>2012年5月14日 晚20:30 第八课 多线程 讲授分时操作、java的线程模型、java中如何编写多线程和运行多线程</p>
<p>2012年5月15日 晚20:30 第八课 多线程  讲授线程的生命周期、线程组和ThreadLocal</p>
<p>2012年5月16日 晚20:30 第八课 多线程  讲授线程的调度(wait、notify、sleep、yield、join、interrupt)</p>
<p>2012年5月17日 晚20:30 第八课 多线程  讲授线程的同步、其他的注意事项(stop、suspend)</p>
<p>2012年5月18日 晚21:00 第八课 多线程  讲授新的线程支持包、线程的应用、常见线程面试问题</p>
<p>2012年5月X日(待定，具体加群4885880) 晚21:00 第九课 数据库基础知识及mysql使用</p>
<p> </p>
<p>需要准备的资源：</p>
<p>MySQL 5.5.x版本安装包<br />
mysql-connector-java-5.1.18.tar.gz<br />
mysql-workbench-gpl-5.2.38-win32.msi<br />
并提前安装完毕</p>
<p>jdk7 及其 API文档<br />
myeclipse 8.5到10的任意一个版本<br />
tomcat 7.x<br />
Spring Struts Hibernate框架包<br />
mybatis 的多个开发包<br />
<a href="http://code.google.com/p/mybatis/downloads/list?can=3&amp;q=Product%3DMyBatis" target="_blank">http://code.google.com/p/mybatis &#8230; q=Product%3DMyBatis</a>  mybatis-3.1.0-bundle.zip<br />
<a href="http://code.google.com/p/mybatis/downloads/list?can=3&amp;q=Product%3DSample" target="_blank">http://code.google.com/p/mybatis &#8230; ;q=Product%3DSample</a>   mybatis-jpetstore-6.0.1-bundle.zip</p>
<p>请大家提前准备好开发环境和相关文件。</p>
<p>&nbsp;</p>
<p>1、JDK<br />
我们使用最新的java sdk版本7Ux系列，x为小版本号，去oracle的网站下载最新的版本即可。<br />
2、集成开发环境<br />
使用myeclipse 10，当然用myeclipse 8.x 或者 9.x系列都可以的。<br />
3、servlet容器<br />
使用tomcat 7.x系列，支持最新的servlet 3。<br />
4、数据库<br />
使用mysql 5.5，请同时下载mysql官方的gui工具，现在比较好用了，或者用toad for mysql也可以，记得下载mysql的jdbc驱动包。<br />
5、常用框架包<br />
比如spring 3，struts 2，hibernate 3，mybatis 3等，下载最新版本的即可。</p>
<p>&nbsp;</p>
<p>教学内容：</p>
<p>1、java简介及环境搭建(由来、特点、版本、安装、基本命令、文档、命令行开发、例程、myeclipse安装和使用)<br />
2、java的基本语法一(命名规范、关键字、基本类型、类型转换、基本的输入输出、运算符、流程控制、表达式、数组)<br />
3、java的基本语法二(包、类、方法、常量、变量、静态变量、final关键字、接口、访问控制、内部类、枚举、注解、注释)<br />
4、java中面向对象概念(封装、继承、多态、抽象方法、反射、泛型、单例模式)<br />
5、java常用类及其方法(String/StringBuffer，StringBuilder，Collection及其子类[集合类]、Vector及其子类、System等)<br />
6、java的JVM及垃圾回收器<br />
7、java异常处理和安全(异常、调试和断言)<br />
8、多线程<br />
9、数据库基础知识，mysql使用<br />
10、jdbc编程<br />
11、java的I/O编程(基本I/O类、序列化)<br />
12、网络编程(socket及URL和URI等常用类)<br />
13、tomcat初步<br />
14、jsp和servlet初步<br />
15、国际化和JNI<br />
16、XML操作<br />
17、设计模式<br />
18、spring、struts、hibernate、mybatis等等框架<br />
19、综合样例</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=271</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>修改增加Oracle最大连接数的最简单方法</title>
		<link>http://www.javastar.org/?p=264</link>
		<comments>http://www.javastar.org/?p=264#comments</comments>
		<pubDate>Tue, 27 Mar 2012 04:28:25 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[数据库技术]]></category>
		<category><![CDATA[oracle]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=264</guid>
		<description><![CDATA[很简单，只需要执行本步骤的第一步就完成了 1、修改Oracle最大连接数的方法 a、以sysdba身份登陆PL/SQL 或者 Worksheet b、查询目前连接数 show parameter processes; c、更改系统连接数 alter system set processes=1000 scope=spfile; d、创建pfile（这步一定要做，否则可能无法启动oracle） create pfile from spfile; e、重启Oracle服务或重启Oracle服务器 2、查询Oracle游标使用情况的方法 select * from v$open_cursor where user_name = &#8216;TRAFFIC&#8217;； 3、查询Oracle会话的方法 select * from v$session 有人说还要修改sessions，运行 alter system set sessions=300 scope=spfile; 其实这个不修改也可以的，因为sessions是个派生值,由processes的值决定,公式sessions=1.1*process + 5。 很简单吧！ process:这个参数限制了能够连接到SGA的操作系统进程数(或者是Windows 系统中的线程数),这个总数必须足够大,从而能够适用于后台进程与所有的专用服务器进程,此外,共享服务器进程与调度进程的数目也被计算在内.此外,共享 服务器进程与调度进程的数目也被计算在内.因此,在专用服务器环境中,这是一种限制并发连接数的方法. Sessions:是被应用于oracle层次而非操作系统层次.在不考虑通过专用服务器或共享服务器进行登录的情况下,这个参数限制了对指定实例的并发登陆数.]]></description>
			<content:encoded><![CDATA[<p>很简单，只需要执行本步骤的第一步就完成了</p>
<p>1、修改Oracle最大连接数的方法<br />
a、以sysdba身份登陆PL/SQL 或者 Worksheet<br />
b、查询目前连接数<br />
show parameter processes;<br />
c、更改系统连接数<br />
alter system set processes=1000 scope=spfile;<br />
d、创建pfile（这步一定要做，否则可能无法启动oracle）<br />
create pfile from spfile;<br />
e、重启Oracle服务或重启Oracle服务器</p>
<p><span id="more-264"></span>2、查询Oracle游标使用情况的方法<br />
select * from v$open_cursor where user_name = &#8216;TRAFFIC&#8217;；</p>
<p>3、查询Oracle会话的方法<br />
select * from v$session</p>
<p>有人说还要修改sessions，运行</p>
<p>alter system set sessions=300 scope=spfile;</p>
<p>其实这个不修改也可以的，因为sessions是个派生值,由processes的值决定,公式sessions=1.1*process + 5。</p>
<p>很简单吧！</p>
<p>process:这个参数限制了能够连接到SGA的操作系统进程数(或者是Windows 系统中的线程数),这个总数必须足够大,从而能够适用于后台进程与所有的专用服务器进程,此外,共享服务器进程与调度进程的数目也被计算在内.此外,共享 服务器进程与调度进程的数目也被计算在内.因此,在专用服务器环境中,这是一种限制并发连接数的方法.</p>
<p>Sessions:是被应用于oracle层次而非操作系统层次.在不考虑通过专用服务器或共享服务器进行登录的情况下,这个参数限制了对指定实例的并发登陆数.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=264</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>给创业新人的42条建议</title>
		<link>http://www.javastar.org/?p=261</link>
		<comments>http://www.javastar.org/?p=261#comments</comments>
		<pubDate>Thu, 15 Mar 2012 12:20:56 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[创业之路]]></category>
		<category><![CDATA[创业，建议]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=261</guid>
		<description><![CDATA[一下42条建议是注明投资人Mark Suster送给创业者的，句句真言，对比思考，会受益良多。 1、创业还是继续打工？这取决于现阶段你想赚钱还是想学习； 2、要及早避免”侵犯知识产权“之类的重大错误，请好律师； 3、理清商业计划，即使不写成文档，也必须有好的财务模型； 4、谨慎选择投资人，不要因为太心切而答应他们的不合理要求； 5、明确自己的优劣势，寻找合适的合作伙伴； 6、听取客户和员工的意见，不要盲目遵从自己的想法； 7、拓展人脉，抓住机遇； 8、不要怕犯错，实践出真知； 9、清楚自己有多少流动资金； 10、不但要知彼也要知己，经常自省； 11、雇佣有激情的一线员工，不要过早引入太多高管； 12、经常与员工互动，你能了解到很多好想法； 13、迅速行动，在施行过程中矫正方向； 14、培养自己的领导才能； 15、明确公司定位，只为特定人群开发的产品更容易成功； 16、广泛收集反馈，即使是不良反馈，找到需要修改的地方； 17、沉着冷静，着眼点要广，不要得意的太早； 18、不要怕竞争； 19、学会变通，总是有你意想不到的情况出现； 20、不要事必躬亲，你没有那么多精力，把任务分配给放心的人； 21、了解客户需求； 22、学会谈判； 23、学会放低姿态，请求别人的原谅； 24、想办法得到真实的数据； 25、记住教训，别好了伤疤忘了疼； 26、尊重优秀员工，升职、加薪，用尽办法保留公司骨干； 27、开好董事会； 28、设立意见栏，奖励提出好建议的人 29、销售产品之前想明白 3 个问题：1）客户为什么要买东西？2）为什么要买我的产品？3）为什么现在就要买？ 30、顽强，置之死地而后生并不是奇迹； 31、制定明确的战略计划； 32、热爱自己的事业，主动积极地工作； 33、不听信谣言； 34、宣传你的产品，选择合适的演示平台； 35、注册品牌，保护好自己的专利； 36、在合理的时候分红； 37、不要以学历定人才； 38、慷慨待人； 39、勇于面对风险，但是要知道如何全身而退； 40、在会议上拓展人脉，在这种地方能遇见很多可以给你意见和帮助的人； 41、在大型会议上镇定自若，这并不容易，尤其在面对代表不同利益的各方人士时； 42、保持身体健康，这一点尤为重要。]]></description>
			<content:encoded><![CDATA[<p>一下42条建议是注明投资人Mark Suster送给创业者的，句句真言，对比思考，会受益良多。</p>
<p>1、创业还是继续打工？这取决于现阶段你想赚钱还是想学习；</p>
<p>2、要及早避免”侵犯知识产权“之类的重大错误，请好律师；</p>
<p>3、理清商业计划，即使不写成文档，也必须有好的财务模型；</p>
<p>4、谨慎选择投资人，不要因为太心切而答应他们的不合理要求；</p>
<p>5、明确自己的优劣势，寻找合适的合作伙伴；</p>
<p><span id="more-261"></span>6、听取客户和员工的意见，不要盲目遵从自己的想法；</p>
<p>7、拓展人脉，抓住机遇；</p>
<p>8、不要怕犯错，实践出真知；</p>
<p>9、清楚自己有多少流动资金；</p>
<p>10、不但要知彼也要知己，经常自省；</p>
<p>11、雇佣有激情的一线员工，不要过早引入太多高管；</p>
<p>12、经常与员工互动，你能了解到很多好想法；</p>
<p>13、迅速行动，在施行过程中矫正方向；</p>
<p>14、培养自己的领导才能；</p>
<p>15、明确公司定位，只为特定人群开发的产品更容易成功；</p>
<p>16、广泛收集反馈，即使是不良反馈，找到需要修改的地方；</p>
<p>17、沉着冷静，着眼点要广，不要得意的太早；</p>
<p>18、不要怕竞争；</p>
<p>19、学会变通，总是有你意想不到的情况出现；</p>
<p>20、不要事必躬亲，你没有那么多精力，把任务分配给放心的人；</p>
<p>21、了解客户需求；</p>
<p>22、学会谈判；</p>
<p>23、学会放低姿态，请求别人的原谅；</p>
<p>24、想办法得到真实的数据；</p>
<p>25、记住教训，别好了伤疤忘了疼；</p>
<p>26、尊重优秀员工，升职、加薪，用尽办法保留公司骨干；</p>
<p>27、开好董事会；</p>
<p>28、设立意见栏，奖励提出好建议的人</p>
<p>29、销售产品之前想明白 3 个问题：1）客户为什么要买东西？2）为什么要买我的产品？3）为什么现在就要买？</p>
<p>30、顽强，置之死地而后生并不是奇迹；</p>
<p>31、制定明确的战略计划；</p>
<p>32、热爱自己的事业，主动积极地工作；</p>
<p>33、不听信谣言；</p>
<p>34、宣传你的产品，选择合适的演示平台；</p>
<p>35、注册品牌，保护好自己的专利；</p>
<p>36、在合理的时候分红；</p>
<p>37、不要以学历定人才；</p>
<p>38、慷慨待人；</p>
<p>39、勇于面对风险，但是要知道如何全身而退；</p>
<p>40、在会议上拓展人脉，在这种地方能遇见很多可以给你意见和帮助的人；</p>
<p>41、在大型会议上镇定自若，这并不容易，尤其在面对代表不同利益的各方人士时；</p>
<p>42、保持身体健康，这一点尤为重要。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=261</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>google员工谈产品经理应该具备的素质</title>
		<link>http://www.javastar.org/?p=259</link>
		<comments>http://www.javastar.org/?p=259#comments</comments>
		<pubDate>Sat, 03 Mar 2012 13:17:56 +0000</pubDate>
		<dc:creator>junsan</dc:creator>
				<category><![CDATA[团队建设管理]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[产品经理]]></category>

		<guid isPermaLink="false">http://www.javastar.org/?p=259</guid>
		<description><![CDATA[优秀的Google产品经理需要具备哪些素质？前google工程师 Edward 回答了该问题： 在 Google ，我和我所见到过的最优秀的产品经理一起工作过，我会根据自己的经历出一个列表。由于我不是项目经理，所以这些结论都是我在 Google 观察最优秀的产品经理后的结果。 1. 对产品以及所有相关的问题负责。这会让你积极主动，你是第一个寻找bug的人，第一个与用户沟通的人，以 及第一个担心产品是否合格的人。你总是第一个自愿为产品或团队做各种任务的志愿者，像是做会议记录、给客户发邮件、填补临时的空缺、为bug确定优先级， 或是快速做出一个实体模型。始终持有这样一个想法：这不是别人的责任，这就是你的责任。当你这么做的时候，你会发现第2条会更容易。 2. 具备难以置信的说服力。（我不知道这是如何做到的，但每天我都会看到）你希望把事情完成，但你不是负责人，所以只能去说服别人。没有哪个团队向你汇报，也没有任何人会按照你的说法行事。在 Google ，你需要通过使别人信服而不是发号施令来完成事情。如果你正在做第1条，事情会变得简单，因为每个人都知道如果有人攻击这个产品，你和他们会位于同一个战壕。 3. 成为一名工程师。我并不是说你真的需要为产品编写代码。我想说的是，你应当像一名工程师那样对产品的构造 过程具有好奇心。你应该了解产品功能在开发过程需要的成本，以及为什么开发成本会变得这么高。那个特性使用的是什么算法？为什么这个页面会呈现得很慢？大 的架构变动对产品会产生影响，团队中的每个工程师都会对此非常重视，你也应该如此。如果你遇到项目的负责人，他们想要知道一些具体的事情，你应该能够为他 们解释一些主要的工程方面的决定以及之前的利弊权衡。在谷歌，最好的的产品经理都会尽可能地变得更加技术化并乐此不疲。 4. 积极，再积极一点。你的团队很可能全部由工程师组成，并且中的一些可能非常愤世嫉俗。一个非常积极向上的 产品经理能够在团队中创造一种包容的氛围。尽管每时每刻都保持积极看上去很可笑，但是积极是有传染性的，你的团队会依赖上它。请记住，你和主要的工程师 （技术负责人）可能会列出百万种让你沮丧的事情，但是团队中的其他人不应该知道这一切。因为你是产品经理，所以不应该沉浸在自己的担心中，这样会帮助他们 更好地完成工作。你就是团队面向整个公司其他部门的窗口和信使。如果你变得消极，团队就会因此认为公司里其他人也是这么看待他们的工作。 5. 不要自我推荐。这是显而易见的，如果你这么做了，不但非常无聊而且对自身也有害。赞美团队中的其他人，你和技术负责人（们）已经是项目的主要联系人，因而不要做任何的推荐。如果你拿别人的辛苦劳动用来为自己博得赞赏，你不仅错了而且不会得逞。要心胸宽广。无 论是撰写项目博客，还是产品新特性的午餐视频发布会，最优秀的产品经理都应该推荐团队的其他成员。看看谷歌最优秀的产品博客，你就会发现这些博客的作者并 不总是由产品经理，反而会是团队中的各个成员。产品经理会积极推荐其他人。（请不要误解我这里所说的“推荐” promotion ，这和升职是完全不同的。顺便说一下，在谷歌升职是和绩效考核紧密相关的。） 6. 无所畏惧。这个名词如果是作家来解释可能会更好，但请你不要被字面意思所迷惑。最好的产品经理向领导汇报的内容和给团队中的工程师或设计师讲述的内容应该是一样的。如果你在被领导质问产品设计所作的决定时默不作声，你肯定不会成功。做出简洁明了的回答，并无所畏惧地为你团队的创意辩护。]]></description>
			<content:encoded><![CDATA[<p>优秀的Google产品经理需要具备哪些素质？前google工程师 Edward 回答了该问题：</p>
<p>在 Google ，我和我所见到过的最优秀的产品经理一起工作过，我会根据自己的经历出一个列表。由于我不是项目经理，所以这些结论都是我在 Google 观察最优秀的产品经理后的结果。</p>
<p><span id="more-259"></span>1. <strong>对产品以及所有相关的问题负责。</strong>这会让你积极主动，你是第一个寻找bug的人，第一个与用户沟通的人，以 及第一个担心产品是否合格的人。你总是第一个自愿为产品或团队做各种任务的志愿者，像是做会议记录、给客户发邮件、填补临时的空缺、为bug确定优先级， 或是快速做出一个实体模型。始终持有这样一个想法：<strong>这不是别人的责任，这就是你的责任</strong>。当你这么做的时候，你会发现第2条会更容易。</p>
<p>2. <strong>具备难以置信的说服力。</strong>（我不知道这是如何做到的，但每天我都会看到）你希望把事情完成，但你不是负责人，所以只能去说服别人。没有哪个团队向你汇报，也没有任何人会按照你的说法行事。<strong>在 Google ，你需要通过使别人信服而不是发号施令来完成事情。</strong>如果你正在做第1条，事情会变得简单，因为每个人都知道如果有人攻击这个产品，你和他们会位于同一个战壕。</p>
<p>3. <strong>成为一名工程师。</strong>我并不是说你真的需要为产品编写代码。我想说的是，你应当像一名工程师那样对产品的构造 过程具有好奇心。你应该了解产品功能在开发过程需要的成本，以及为什么开发成本会变得这么高。那个特性使用的是什么算法？为什么这个页面会呈现得很慢？大 的架构变动对产品会产生影响，团队中的每个工程师都会对此非常重视，你也应该如此。如果你遇到项目的负责人，他们想要知道一些具体的事情，你应该能够为他 们解释一些主要的工程方面的决定以及之前的利弊权衡。在谷歌，最好的的产品经理都会尽可能地<strong>变得更加技术化并乐此不疲</strong>。</p>
<p>4. <strong>积极，再积极一点。</strong>你的团队很可能全部由工程师组成，并且中的一些可能非常愤世嫉俗。一个非常积极向上的 产品经理能够在团队中创造一种包容的氛围。尽管每时每刻都保持积极看上去很可笑，但是积极是有传染性的，你的团队会依赖上它。请记住，你和主要的工程师 （技术负责人）可能会列出百万种让你沮丧的事情，但是团队中的其他人不应该知道这一切。因为你是产品经理，所以不应该沉浸在自己的担心中，这样会帮助他们 更好地完成工作。<strong>你就是团队面向整个公司其他部门的窗口和信使。</strong>如果你变得消极，团队就会因此认为公司里其他人也是这么看待他们的工作。<br />
<img title="如何在Google成为一名优秀的产品经理？" src="http://alibuybuy-img11.stor.sinaapp.com/2012/02/2279_10021401532870799.jpg" alt="如何在Google成为一名优秀的产品经理？" width="460" height="345" /></p>
<p>5.<strong> 不要自我推荐。</strong>这是显而易见的，如果你这么做了，不但非常无聊而且对自身也有害。赞美团队中的其他人，你和技术负责人（们）已经是项目的主要联系人，因而不要做任何的推荐。如果你拿别人的辛苦劳动用来为自己博得赞赏，你不仅错了而且不会得逞。<strong>要心胸宽广。</strong>无 论是撰写项目博客，还是产品新特性的午餐视频发布会，最优秀的产品经理都应该推荐团队的其他成员。看看谷歌最优秀的产品博客，你就会发现这些博客的作者并 不总是由产品经理，反而会是团队中的各个成员。产品经理会积极推荐其他人。（请不要误解我这里所说的“推荐” promotion ，这和升职是完全不同的。顺便说一下，在谷歌升职是和绩效考核紧密相关的。）</p>
<p>6. <strong>无所畏惧。</strong>这个名词如果是作家来解释可能会更好，但请你不要被字面意思所迷惑。最好的产品经理向领导汇报的内容和给团队中的工程师或设计师讲述的内容应该是一样的。如果你在被领导质问产品设计所作的决定时默不作声，你肯定不会成功。做出简洁明了的回答，并<strong>无所畏惧地为你团队的创意辩护。</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://www.javastar.org/?feed=rss2&#038;p=259</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

