﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-笔记</title><link>http://www.blogjava.net/yuxh/</link><description>way</description><language>zh-cn</language><lastBuildDate>Tue, 12 May 2026 08:57:09 GMT</lastBuildDate><pubDate>Tue, 12 May 2026 08:57:09 GMT</pubDate><ttl>60</ttl><item><title>Hive2.1源码分析(一）启动脚本</title><link>http://www.blogjava.net/yuxh/archive/2017/03/29/432418.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Wed, 29 Mar 2017 08:01:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2017/03/29/432418.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/432418.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2017/03/29/432418.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/432418.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/432418.html</trackback:ping><description><![CDATA[最近在网上看到的相关材料都比较陈旧，也太简略，参看了一下其他人的内容，针对Hive2.1.1做点分享：<br /><div style="margin: 0px; color: #000000; font-family: mononoki, Helvetica, 'Hiragino Sans GB', 微软雅黑, 'Microsoft YaHei UI', SimSun, SimHei, arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px;">1）下载apache-hive-2.1.1-bin.tar.gz</div><div style="margin: 0px; color: #000000; font-family: mononoki,Helvetica,&quot;Hiragino Sans GB&quot;,微软雅黑,&quot;Microsoft YaHei UI&quot;,SimSun,SimHei,arial,sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><p style="margin: 0px;">2）解压缩，下面的命令行如启动报错，请自行查略Hive启动配置</p><div style="margin: 0px;">3）启动<span style="line-height: 1.5;">hiveserver2</span>&nbsp;<span style="line-height: 1.5;">（非必须，使用jdbc访问的时候才使用）<br /><div>bin目录下</div></span></div><div style="margin: 0px;">hive --service hiveserver2 -p10001来启动<span style="line-height: 1.5;">hiveserver2</span>&nbsp;<span style="line-height: 1.5;">服务(默认为10000端口)</span></div><div style="margin: 0px;">nohup hive --service hiverserver2 -p10001可以在后台跑</div><div style="margin: 0px;">4）<span style="line-height: 1.5;">hive脚本运行流程</span><div style="margin: 0px;">bin目录下，使用命令方法为：</div><div style="margin: 0px;"><div>./hive &lt;parameters&gt; --service serviceName &lt;service parameters&gt;</div></div><div style="margin: 0px;">举例：hive --debug :</div><div style="margin: 0px;">&nbsp; &nbsp;查看bin/hive文件</div><div style="margin: 0px;">流程中会判断$1=&#8216;--debug&#8217;则$DEBUG=&#8216;--debug&#8217;</div><div style="margin: 0px;">&nbsp;<div style="margin: 0px;">if [ "$DEBUG" ]; then</div><div style="margin: 0px;">&nbsp; if [ "$HELP" ]; then //<span style="line-height: 1.5;">如还有--help，就会执行debug_help方法。</span></div></div></div><div style="margin: 0px;"><div style="margin: 0px;"><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; debug_help</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; exit 0</div><div style="margin: 0px;">&nbsp; else</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; get_debug_params "$DEBUG"</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; export <span style="color: red;">HADOOP_CLIENT_OPTS</span>="$HADOOP_CLIENT_OPTS $HIVE_MAIN_CLIENT_DEBUG_OPTS"//<span style="line-height: 1.5;">设置HIVE_MAIN_CLIENT_DEBUG_OPTS的参数中加入debug相应参数</span></div><div style="margin: 0px;">&nbsp; fi</div><div style="margin: 0px;">fi</div></div><div style="margin: 0px;"></div><div style="margin: 0px;"><div style="margin: 0px;">if [ "$SERVICE" = "" ] ; then</div><div style="margin: 0px;">&nbsp; if [ "$HELP" = "_help" ] ; then</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; SERVICE="help"</div><div style="margin: 0px;">&nbsp; else</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; SERVICE="cli" &nbsp; &nbsp; //默认赋值cli</div><div style="margin: 0px;">&nbsp; fi</div><div style="margin: 0px;">fi</div></div><div style="margin: 0px;">这个shell脚本很多变量应该是在其他sh文件中定义，其中$SERVICE_LIST就是其他很多sh文件的最开始形成的：export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "</div><div style="margin: 0px;"></div><div style="margin: 0px;"><div style="margin: 0px;">hive脚本最后的<span data-wiz-span="data-wiz-span" style="color: #ff0000;">$TORUN "$@"</span>&nbsp;，默认情况下TORUN其实就是cli,即执行/ext/cli.sh脚本，该脚本中主要是调用/ext/util/execHiveCmd.sh 来执行最后的CliDriver。</div><div style="margin: 0px;">&nbsp;【<span style="line-height: 1.5;">shell脚本中的$*，$@和$#</span><div style="margin: 0px;">举例说：</div><div style="margin: 0px;">脚本名称叫test.sh 入参三个: 1 2 3</div><div style="margin: 0px;">运行test.sh 1 2 3后</div><div style="margin: 0px;">$*为"1 2 3"（一起被引号包住）</div><div style="margin: 0px;">$@为"1" "2" "3"（分别被包住）</div><div style="margin: 0px;">$#为3（参数数量）</div><span data-wiz-span="data-wiz-span">】</span></div><div style="margin: 0px;">即exec $HADOOP jar ${HIVE_LIB}/$JAR<span data-wiz-span="data-wiz-span">&nbsp;$CLASS $HIVE_OPTS "$@" //1<br /></span></div><div style="margin: 0px;">其中:</div><div style="margin: 0px;">$HADOOP=<span style="line-height: 1.5;">$HADOOP_HOME/bin/hadoop</span><span style="line-height: 1.5;">&nbsp;【hive脚本中定义</span><span style="line-height: 1.5;">HADOOP=$HADOOP_HOME/bin/hadoop】</span></div><div style="margin: 0px;">$CLASS=org.apache.hadoop.hive.cli.CliDriver【传入的第一个参数，在cli.sh中有定义】</div><div style="margin: 0px;"></div><div><div style="margin: 0px; color: #000000; font-family: mononoki, Helvetica, 'Hiragino Sans GB', 微软雅黑, 'Microsoft YaHei UI', SimSun, SimHei, arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px;">hadoop脚本（2.7.3为例）中最终会执行：</div><div style="margin: 0px; color: #000000; font-family: mononoki, Helvetica, 'Hiragino Sans GB', 微软雅黑, 'Microsoft YaHei UI', SimSun, SimHei, arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div style="margin: 0px;"># Always respect HADOOP_OPTS and HADOOP_CLIENT_OPTS</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; HADOOP_OPTS="$HADOOP_OPTS $<span data-wiz-span="data-wiz-span" style="color: #ff0000;">HADOOP_CLIENT_OPTS</span>"</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; #make sure security appender is turned off</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; HADOOP_OPTS="$HADOOP_OPTS -Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-INFO,NullAppender}"</div><div style="margin: 0px;">&nbsp;</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; export CLASSPATH=$CLASSPATH</div><div style="margin: 0px;">&nbsp;&nbsp;&nbsp; exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@" //2</div></div><div style="margin: 0px; color: #000000; font-family: mononoki,Helvetica,&quot;Hiragino Sans GB&quot;,微软雅黑,&quot;Microsoft YaHei UI&quot;,SimSun,SimHei,arial,sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;">hive的debug参数就是在启动hive脚本时放到HADOOP_OPTS中的</div></div><div style="margin: 0px;"></div><div style="margin: 0px;"><div><div style="margin: 0px; color: #000000; font-family: mononoki, Helvetica, 'Hiragino Sans GB', 微软雅黑, 'Microsoft YaHei UI', SimSun, SimHei, arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div style="margin: 0px;"><div style="margin: 0px;"><div style="margin: 0px;"><div><div style="margin: 0px; color: #000000; font-family: mononoki, Helvetica, 'Hiragino Sans GB', 微软雅黑, 'Microsoft YaHei UI', SimSun, SimHei, arial, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 21px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 1; word-spacing: 0px; -webkit-text-stroke-width: 0px;"><div style="margin: 0px;"><div style="margin: 0px;"><div style="margin: 0px;">1和2处结合可得到最终的运行命令，查看一下运行结果：ps -ef|grep CliDriver</div></div></div></div></div></div></div></div></div></div><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: #000000; ">&nbsp;&nbsp;</span><span style="color: #000000; ">/</span><span style="color: #000000; ">usr</span><span style="color: #000000; ">/</span><span style="color: #000000; ">java</span><span style="color: #000000; ">/</span><span style="color: #000000; ">jdk1.</span><span style="color: #000000; ">8</span><span style="color: #000000; ">.0_101</span><span style="color: #000000; ">/</span><span style="color: #000000; ">bin</span><span style="color: #000000; ">/</span><span style="color: #000000; ">java&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Xmx256m&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Djava.net.preferIPv4Stack</span><span style="color: #000000; ">=</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Dhadoop.log.dir</span><span style="color: #000000; ">=</span><span style="color: #000000; ">..&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Dhadoop.log.file</span><span style="color: #000000; ">=</span><span style="color: #000000; ">hadoop.log&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Dhadoop.home.dir</span><span style="color: #000000; ">=</span><span style="color: #000000; ">..&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Dhadoop.id.str</span><span style="color: #000000; ">=</span><span style="color: #000000; ">root&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Dhadoop.root.logger</span><span style="color: #000000; ">=</span><span style="color: #000000; ">INFO,console&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Djava.library.path</span><span style="color: #000000; ">=</span><span style="color: #000000; ">..&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Dhadoop.policy.file</span><span style="color: #000000; ">=</span><span style="color: #000000; ">hadoop</span><span style="color: #000000; ">-</span><span style="color: #000000; ">policy.xml&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Djava.net.preferIPv4Stack</span><span style="color: #000000; ">=</span><span style="color: #0000FF; ">true</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Xmx512m&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Dproc_hivecli&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">XX:</span><span style="color: #000000; ">+</span><span style="color: #000000; ">UseParallelGC&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">agentlib:jdwp</span><span style="color: #000000; ">=</span><span style="color: #000000; ">transport</span><span style="color: #000000; ">=</span><span style="color: #000000; ">dt_socket,server</span><span style="color: #000000; ">=</span><span style="color: #000000; ">y,address</span><span style="color: #000000; ">=</span><span style="color: #000000; ">8000</span><span style="color: #000000; ">,suspend</span><span style="color: #000000; ">=</span><span style="color: #000000; ">y&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Dlog4j.configurationFile</span><span style="color: #000000; ">=</span><span style="color: #000000; ">hive</span><span style="color: #000000; ">-</span><span style="color: #000000; ">log4j2.properties&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Djava.util.logging.config.file</span><span style="color: #000000; ">=</span><span style="color: #000000; ">..<br />&nbsp;&nbsp;</span><span style="color: #000000; ">-</span><span style="color: #000000; ">Dhadoop.security.logger</span><span style="color: #000000; ">=</span><span style="color: #000000; ">INFO,NullAppender&nbsp;org.apache.hadoop.util.RunJar </span><span style="color: #000000; "></span><span style="color: #000000; ">/</span><span style="color: #000000; ">yuxh</span><span style="color: #000000; ">/</span><span style="color: #000000; ">app</span><span style="color: #000000; ">/</span><span style="color: #000000; ">apache</span><span style="color: #000000; ">-</span><span style="color: #000000; ">hive</span><span style="color: #000000; ">-</span><span style="color: #000000; ">2</span><span style="color: #000000; ">.</span><span style="color: #000000; ">*/</span><span style="color: #000000; ">lib</span><span style="color: #000000; ">/</span><span style="color: #000000; ">hive</span><span style="color: #000000; ">-</span><span style="color: #000000; ">cli</span><span style="color: #000000; ">-</span><span style="color: #000000; ">2</span><span style="color: #000000; ">.</span><span style="color: #000000; ">*</span><span style="color: #000000;">.jar&nbsp;org.apache.hadoop.hive.cli.CliDriver</span></div></div></div></div></div><img src ="http://www.blogjava.net/yuxh/aggbug/432418.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2017-03-29 16:01 <a href="http://www.blogjava.net/yuxh/archive/2017/03/29/432418.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JBoss Forge 2入门教程</title><link>http://www.blogjava.net/yuxh/archive/2015/09/23/427327.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Wed, 23 Sep 2015 13:14:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2015/09/23/427327.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/427327.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2015/09/23/427327.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/427327.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/427327.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;<a href='http://www.blogjava.net/yuxh/archive/2015/09/23/427327.html'>阅读全文</a><img src ="http://www.blogjava.net/yuxh/aggbug/427327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2015-09-23 21:14 <a href="http://www.blogjava.net/yuxh/archive/2015/09/23/427327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>appfuse3.5打印Hibernate sql参数</title><link>http://www.blogjava.net/yuxh/archive/2015/07/22/426376.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Wed, 22 Jul 2015 06:11:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2015/07/22/426376.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/426376.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2015/07/22/426376.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/426376.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/426376.html</trackback:ping><description><![CDATA[<div style="color: #000000; font-family: 'Segoe UI'; font-size: 14.285715103149414px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">appfuse3.5使用Hibernate4.3.6, 而Hibernate日志框架使用了jboss-logging，想在后台打出sql的参数一直无法生效。</div><div style="color: #000000; font-family: 'Segoe UI'; font-size: 14.285715103149414px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">检查配置文件，框架里面的两个配置文件，src/test/resources/log4j2.xml（单元测试时配置），src/main/resources/log4j2.xml（运行时配置）</div><div style="color: #000000; font-family: 'Segoe UI'; font-size: 14.285715103149414px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">搞清log4j2的配置后，各种修改（主要是</div><div style="color: #000000; font-family: 'Segoe UI'; font-size: 14.285715103149414px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><span style="font-size: 10.5pt; line-height: 1.5;">&nbsp; &lt;Logger name="org.hibernate.SQL" level="trace"/&gt;</span></div><div style="color: #000000; font-family: 'Segoe UI'; font-size: 14.285715103149414px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><span style="font-size: 10.5pt; line-height: 1.5;">&nbsp; &lt;Logger name="org.hibernate.type" level="trace"/&gt;</span>)<br />用junit测试任然无法打印出真实参数。根据这些实践，确定log4j2是使用无误生效的，只是org.hibernate这部分的logger一直未起效</div><div style="color: #000000; font-family: 'Segoe UI'; font-size: 14.285715103149414px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 20px; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;">参考国内外网站，一直无人回答hibernate4的这个问题，有人指出<span style="font-size: 10.5pt; line-height: 1.5;">这部分Hibernate官方文档只是提了一句，一直未更新相关内容。最后有人提到应该是</span>&nbsp;<span style="font-size: 10.5pt; line-height: 1.5;">jboss-logging 的</span><span style="font-size: 10.5pt; line-height: 1.5;">LoggerProviders这个类的问题，看实现对log4j2已经做支持。最后发现&nbsp;</span><span style="font-size: 10.5pt; line-height: 1.5;">jboss-logging使用的是</span><span style="font-size: 10.5pt; line-height: 1.5;">3.2.0.beta，对比相关类的源代码，更改为</span><span style="font-size: 10.5pt; line-height: 1.5;">3.2.0.Final，生效！<br /><br />P.S 把这个问题提交给Appfuse官网，issue APF-1478，作者标志为4.0版本修复。</span></div><img src ="http://www.blogjava.net/yuxh/aggbug/426376.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2015-07-22 14:11 <a href="http://www.blogjava.net/yuxh/archive/2015/07/22/426376.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Andriod webview实现文件上传</title><link>http://www.blogjava.net/yuxh/archive/2012/03/12/371715.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Mon, 12 Mar 2012 04:54:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2012/03/12/371715.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/371715.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2012/03/12/371715.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/371715.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/371715.html</trackback:ping><description><![CDATA[<div>
<div>Andriod 到3.2版本为止，webview方式下使用&lt;input type="file" /&gt;点击后都没有反应。实际上顶层是有隐含的接口没实现的，可以自己重写这个方法来实现。以phonegap为例：<br />
<br />
<div style="background-color: #eeeeee; font-size: 13px; border: 1px solid #cccccc; padding: 4px 5px 4px 4px; width: 98%;"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">&nbsp;App&nbsp;</span><span style="color: #0000FF; ">extends</span><span style="color: #000000; ">&nbsp;DroidGap&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;ValueCallback</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Uri</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;mUploadMessage;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">private</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">final</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">static</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;FILECHOOSER_RESULTCODE&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">1</span><span style="color: #000000; ">;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">/**</span><span style="color: #008000; ">&nbsp;Called&nbsp;when&nbsp;the&nbsp;activity&nbsp;is&nbsp;first&nbsp;created.&nbsp;</span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;onCreate(Bundle&nbsp;savedInstanceState)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">super</span><span style="color: #000000; ">.onCreate(savedInstanceState);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">super</span><span style="color: #000000; ">.init();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;WebView&nbsp;wv&nbsp;=&nbsp;new&nbsp;WebView(this);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;wv.setWebViewClient(new&nbsp;WebViewClient());</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.appView.setWebChromeClient(</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;CordovaChromeClient(App.</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;For&nbsp;Android&nbsp;3.0+</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;openFileChooser(ValueCallback</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Uri</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;uploadMsg,&nbsp;String&nbsp;acceptType)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mUploadMessage&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;uploadMsg;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Intent&nbsp;i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Intent(Intent.ACTION_GET_CONTENT);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i.addCategory(Intent.CATEGORY_OPENABLE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i.setType(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">image/*</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;App.</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.startActivityForResult(Intent.createChooser(i,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">File&nbsp;Chooser</span><span style="color: #000000; ">"</span><span style="color: #000000;">),&nbsp;FILECHOOSER_RESULTCODE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;The&nbsp;undocumented&nbsp;magic&nbsp;method&nbsp;override<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;Eclipse&nbsp;will&nbsp;swear&nbsp;at&nbsp;you&nbsp;if&nbsp;you&nbsp;try&nbsp;to&nbsp;put&nbsp;@Override&nbsp;here</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">public</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;openFileChooser(ValueCallback</span><span style="color: #000000; ">&lt;</span><span style="color: #000000; ">Uri</span><span style="color: #000000; ">&gt;</span><span style="color: #000000; ">&nbsp;uploadMsg)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mUploadMessage&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;uploadMsg;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Intent&nbsp;i&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">new</span><span style="color: #000000; ">&nbsp;Intent(Intent.ACTION_GET_CONTENT);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i.addCategory(Intent.CATEGORY_OPENABLE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i.setType(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">image/*</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;App.</span><span style="color: #0000FF; ">this</span><span style="color: #000000; ">.startActivityForResult(Intent.createChooser(i,&nbsp;</span><span style="color: #000000; ">"</span><span style="color: #000000; ">File&nbsp;Chooser</span><span style="color: #000000; ">"</span><span style="color: #000000; ">),&nbsp;App.FILECHOOSER_RESULTCODE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000; ">//</span><span style="color: #008000; ">&nbsp;setContentView(wv);</span><span style="color: #008000; "><br />
</span><span style="color: #000000; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">super</span><span style="color: #000000; ">.loadUrl(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">file:///android_asset/www/login.html</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;@Override<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">protected</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">void</span><span style="color: #000000; ">&nbsp;onActivityResult(</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;requestCode,&nbsp;</span><span style="color: #0000FF; ">int</span><span style="color: #000000; ">&nbsp;resultCode,&nbsp;Intent&nbsp;intent)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(requestCode&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;FILECHOOSER_RESULTCODE)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">if</span><span style="color: #000000; ">&nbsp;(</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;mUploadMessage)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000FF; ">return</span><span style="color: #000000; ">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Uri&nbsp;result&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;intent&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">&nbsp;</span><span style="color: #000000; ">||</span><span style="color: #000000; ">&nbsp;resultCode&nbsp;</span><span style="color: #000000; ">!=</span><span style="color: #000000; ">&nbsp;RESULT_OK&nbsp;</span><span style="color: #000000; ">?</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000; ">&nbsp;:&nbsp;intent.getData();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mUploadMessage.onReceiveValue(result);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mUploadMessage&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #0000FF; ">null</span><span style="color: #000000;">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
</div>
</div>
如果直接的webview方式，extends  WebChromeClient即可。
参考：http://stackoverflow.com/questions/5907369/file-upload-in-webview
<img src ="http://www.blogjava.net/yuxh/aggbug/371715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2012-03-12 12:54 <a href="http://www.blogjava.net/yuxh/archive/2012/03/12/371715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RCP与Document风格</title><link>http://www.blogjava.net/yuxh/archive/2011/10/08/360224.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Sat, 08 Oct 2011 13:47:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2011/10/08/360224.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/360224.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2011/10/08/360224.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/360224.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/360224.html</trackback:ping><description><![CDATA[<p>有两种SOAP message风格，<em>document</em> 和<em>RPC，</em>他们定义了SOAP message body的格式。使用document风格时（包括wrapped和unwrapped），在wsdl中有一个非空的types部分，这个部分用XML Schema language定义了web service要用到的类型。<em>wsgen</em>工具从SIB（有SEI就足够了）中生成与XSD对应的java类。用java代码生成WSDL文件的时候需要一些java类，<em>wsgen</em>工具可以生成这些Java类，生成的这些java类被称为<em>wsgen</em> artifacts，底层的JWS类库会用到这些类，特别是JAX-B系列的包，会用来转换(marshal)java类实例(that is, Java in-memory objects)为XML类型的XML实例（满足XML Schema document的XML文档实例），</p> <p>The inverse operation is used to convert (unmarshal) an XML document instance to an in-memory<br>object, an object of a Java type or a comparable type in some other language。因此<em>wsgen</em>工具生成的artifacts，支持了Java为基础的web service的互操作性。JAX-B类库提供了Java和XSD类型转换的底层支持。</p> <p>For the most part, the wsgen utility can be used without our bothering to inspect the artifacts that it produces. For the most part, JAX-B remains unseen infrastructure.</p> <p><em>wsgen</em> artifacts实际上是wsdl message的数据类型，他们和XML Schema type绑定，每个message的XML Schema types从这些java类型得来的。注：在当前的jdk1.6.24中，已经融入wsgen自动生成的过程，不需手动调用。</p> <p><em>wsgen</em>工具可用来生成wsdl文件，如：% wsgen -cp "." -wsdl ch01.ts.TimeServerImpl 。这为TimeServer服务生成了wsdl。用wsgen生成的wsdl和通过访问发布的服务生成的wsdl 有个很大的区别：wsgen生成的没有endpoint,因为这个URL是在发布服务的时候决定的。其他地方两个wsdl是相同的。</p> <p><em>wsimport(</em>以前叫wsdl2java和 java2wsdl更形象<em>)</em>工具可使用WSDL生成用来帮助写客户端的artifacts .</p> <p>1 先契约再编码方式<br>一个例子：得到一个tempConvert.wsdl文件，使用命令 wsimport -keep -p ch02.tc tempConvert.wsdl ，命令根据wsdl的portType生成一个SEI类，把SEI的interface换为class，再把方法改为实现就可变为SIB。把该SIB发布，再使用命令wsimport -keep -p clientTC <a href="http://localhost:5599/tc?wsdl">http://localhost:5599/tc?wsdl</a>，来生成客户端辅助类<br>2 编码优先<br>服务被发布之后，会自动生成WSDL供客户端使用。然而，使用annotations可以控制WSDL或WSDL-generated artifacts的生成。</p><img src ="http://www.blogjava.net/yuxh/aggbug/360224.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2011-10-08 21:47 <a href="http://www.blogjava.net/yuxh/archive/2011/10/08/360224.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>区分getPath(), getAbsolutePath(), getCanonicalPath()</title><link>http://www.blogjava.net/yuxh/archive/2011/06/24/352951.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Fri, 24 Jun 2011 05:42:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2011/06/24/352951.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/352951.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2011/06/24/352951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/352951.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/352951.html</trackback:ping><description><![CDATA[<div><p>来自<div>http://stackoverflow.com/questions/1099300/whats-the-difference-between-getpath-getabsolutepath-and-getcanonicalpath</div><br /></p><p>C:\temp\file.txt" - this is a path, an absolute path, a canonical path</p>  <p>.\file.txt This is a path, It's not an absolute path nor canonical path.</p>  <p><code>C:\temp\myapp\bin\..\\..\file.txt</code> This is a path, and an absolute path, it's not a canonical path</p>  <p>Canonical path is always an absolute path.</p></div><div>Converting from a path to a canonical path makes it absolute (通常会处理改变当前目录，所以像. ./file.txt 变为c:/temp/file.txt). The  canonical path of a file just "purifies" the  path, 去除和解析类似&#8220; ..\&#8221; and resolving symlinks(on  unixes)</div><div><div><p>In short:</p>  <ul><li>getPath() gets the path string that the File object was constructed with, and it may be relative current directory.</li><li>getAbsolutePath() gets the path string after resolving it against  the current directory if it's relative, resulting in a fully qualified  path.</li><li>getCanonicalPath() gets the path string after resolving any relative  path against current directory, and removes any relative pathing (. and  ..), and any file system links to return a path which the file system  considers the canonical means to reference the file system object to  which it points.</li></ul>  <p>Also, each of this has a File equivalent which returns the corresponding File object.</p> </div></div><div><p>The best way I have found to get a feel for things like this is to try them out:</p>  <pre prettyprint=""><code>import java.io.File;<br />public class PathTesting {<br />&nbsp; &nbsp; &nbsp; &nbsp; public static void main(String [] args) {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; File f = new File("test/.././file.txt");<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(f.getPath());<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(f.getAbsolutePath());<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println(f.getCanonicalPath());<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br />&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; catch(Exception e) {}<br />&nbsp; &nbsp; &nbsp; &nbsp; }<br />}<br /></code></pre>  <p>Your output will be something like:</p>  <pre prettyprint=""><code>test\..\.\file.txt<br />C:\projects\sandbox\trunk\test\..\.\file.txt<br />C:\projects\sandbox\trunk\file.txt<br /></code></pre>  <p>So, <code>getPath()</code> gives you the path based on the File object, which may or may not be relative; <code>getAbsolutePath()</code> gives you an absolute path to the file; and <code>getCanonicalPath()</code>  gives you the unique absolute path to the file. Notice that there are a  huge number of absolute paths that point to the same file, but only one  canonical path.</p>  When to use each? Depends on what you're trying to accomplish, but if you were trying to see if two <code>Files</code> are pointing at the same file on disk, you could compare their canonical paths.</div><img src ="http://www.blogjava.net/yuxh/aggbug/352951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2011-06-24 13:42 <a href="http://www.blogjava.net/yuxh/archive/2011/06/24/352951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XML介绍</title><link>http://www.blogjava.net/yuxh/archive/2011/03/24/346908.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Thu, 24 Mar 2011 01:05:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2011/03/24/346908.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/346908.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2011/03/24/346908.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/346908.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/346908.html</trackback:ping><description><![CDATA[<p>DTDs  <p>Introduced as part of the XML 1.0 specification, <a name="Id619e0_927896"></a>DTDs are the oldest constraint model around in the XML world. They're simply to use, but this simplicity comes at a price: DTDs are inflexible, and offer you little for data type validation as well.  <p>XML Schema (XSD)  <p><a name="Id622e0_927897"></a>XML Schema is the <a name="Id625e0_927898"></a>W3C's anointed successor to DTDs. XML Schemas are literally orders of magnitude more flexible than DTDs, and offer an almost dizzying array of support for various data types. However, just as DTDs were simple and limited, XML Schemas are flexible, complex, and (some would argue) bloated. It takes a lot of work to write a good schema, even for 50- or 100-line XML documents. For this reason, there's been a lot of dissatisfaction with XML Schema, even though they are widely being used.<pre><tt><i>[prefix]</i></tt>:<tt><i>[element name]</i></tt></pre><pre><tt><strong>元素：<br></strong></tt>root元素必须包含所有文档中的元素，只能有一个root元素。元素名只能以下划线或字母开头，不能有空格，区分大小写。开元素必须有对应闭元素（也有类似html的简写，如&lt;img src="http://www.blogjava.net/images/xml.gif" /&gt;）。文档由DTD或schema来限制它是否合格。</pre><pre><strong>属性：<br></strong>什么时候用属性？基本原则：多个值的数据用元素，单值的数据用元素。如果数据有很多值或者比较长，数据最可能属于元素。他主要被当作文本，容&lt;rss:author&gt;Doug Hally&lt;/rss:author&gt; &lt;journal:author&gt;Neil Gaiman&lt;/journal:author&gt;易搜索，好用。比如一本书的章节描述。然而如果数据主要作为单值处理的话，最好作为属性。如果搞不清楚，可以安全的使用元素。</pre><pre><strong>命名空间Namespaces：<br></strong>xml的命名空间是一种用一个特定的URI来关联XML文档里的一个或多个元素的方法。意味着元素是由名字和命名空间一起来识别的。许多复杂的XML文件里，同一个名字会有多个用途。比如，一个RSS feed有一个作者，这个作者同时是每个日记的。虽然这些数据都用author元素来表示，但他们不应该被当作同一个<em><font color="#c0504d">类型</font></em>的数据。命名空间很好的解决了这个问题，命名空间说明书要求一个前缀和唯一的URI联合起来区分不同命名空间里的元素。如<a href="http://www.neilgaiman.com/entries">http://www.neilgaiman.com/entries</a>作为URI，联合前缀<tt>journal用来表示日志相关的元素。<br></tt>&lt;rdf:RDF xmlns:rss="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:journal="http://www.neilgaiman.com/entries"&gt;，然后就可使用了：<br>&lt;rss:author&gt;Doug Hally&lt;/rss:author&gt; &lt;journal:author&gt;Neil Gaiman&lt;/journal:author&gt;实际上在使用命名空间前缀的时候再定义也可以的：<br>&lt;rss:author xmlns:rss="http://www.w3.org/1999/02/22-rdf-syntax-ns#"&gt;Doug Hally&lt;/rss:author&gt;<br>如果名字没有命名空间，不代表在默认命名空间中，而是xml处理器以在任何命名空间以外方式解释他。要声明默认命名空间的话就不用后面冒号部分，如&lt;Insured xmlns="<a href="http://www.IBM.com/software">http://www.IBM.com/software</a>"&gt; <br><strong>使用的一些术语</strong>:</pre>
<ul>
<li>
<p>The name of a namespace (such as <a href="http://www.ibm.com/software">http://www.ibm.com/software</a>) is the <i>namespace URI</i>.</p>
<li>
<p>The element or attribute name can include a prefix and a colon (as in prod:Quantity). A name in that form is called a <i>qualified name</i>, or<em> <font color="#d19049">QName</font></em>, and the identifier that follows the colon is called a<font color="#d19049"> <i>local name</i></font>. If a prefix is not in use, neither is the colon, and the QName and local name are identical.</p>
<li>
<p>An XML identifier (such as a local name) that has no colon is sometimes called an <font color="#d19049"><i>NCName</i>.</font> (The <i>NC</i> comes from the phrase <i>no colon</i>.)</p></li></ul>
<p><a name="Id328e0_958409"></a><strong>Entity references</strong>:<br>用来处理转义字符，语法是<font color="#c0504d"><tt>&amp;</tt> <tt><i>[entity name]</i></tt> <tt>;<font color="#000000">XML解析器碰到这种entity reference，就会用对应的值替换掉他。如<tt>&amp;lt;（&lt;）,<tt>&amp;gt;(&gt;),<tt><tt>&amp;amp;<tt><a name="Id337e0_958413"></a><a name="Id337e5_958413"></a>(&amp;),&amp;quot;("),<tt>&amp;apos;(')。注意entity reference是用户可定义的。比如多处用到版权提示，自己定义后以后更改就方便了：</tt></tt></tt></tt></tt></tt></font></tt></font>&lt;ora:copyright&gt;&amp;OReillyCopyright;&lt;/ora:copyright&gt;。除了用来表示数据中的复杂或特殊字符外，entity reference还会有更多用途。</p>
<p><strong>不解析的数据</strong>：<br>当传输大量数据给应用且不用xml解析的时候，CDATA就有用了。当大量的字符需要用entity reference转义的时候，或空格必须保留的时候，使用CDATA。&lt;![CDATA[….]]&gt;<font color="#c0504d"><br></p></font><img src ="http://www.blogjava.net/yuxh/aggbug/346908.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2011-03-24 09:05 <a href="http://www.blogjava.net/yuxh/archive/2011/03/24/346908.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>js分割csv文件 </title><link>http://www.blogjava.net/yuxh/archive/2010/12/03/339669.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Fri, 03 Dec 2010 01:06:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2010/12/03/339669.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/339669.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2010/12/03/339669.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/339669.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/339669.html</trackback:ping><description><![CDATA[转自<a href="http://www.bennadel.com/blog/1504-Ask-Ben-Parsing-CSV-Strings-With-Javascript-Exec-Regular-Expression-Command.htm">http://www.bennadel.com/blog/1504-Ask-Ben-Parsing-CSV-Strings-With-Javascript-Exec-Regular-Expression-Command.htm</a>，把csv文件按分隔符切割后放在数组中。
<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 4px; background-color: #eeeeee; padding-left: 4px; width: 98%; padding-right: 5px; font-size: 13px; word-break: break-all; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 4px"><img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /><span style="color: #008000">//</span><span style="color: #008000">&nbsp;This&nbsp;will&nbsp;parse&nbsp;a&nbsp;delimited&nbsp;string&nbsp;into&nbsp;an&nbsp;array&nbsp;of</span><span style="color: #008000">&nbsp;arrays.&nbsp;<br />
&nbsp;&nbsp;&nbsp;// The&nbsp;default&nbsp;delimiter&nbsp;is&nbsp;the&nbsp;comma,&nbsp;but&nbsp;this</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /></span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;can&nbsp;be&nbsp;overriden&nbsp;in&nbsp;the&nbsp;second&nbsp;argument.</span><span style="color: #008000"><br />
<img id="Codehighlighter1_200_1908_Open_Image" onclick="this.style.display='none'; Codehighlighter1_200_1908_Open_Text.style.display='none'; Codehighlighter1_200_1908_Closed_Image.style.display='inline'; Codehighlighter1_200_1908_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" /><img style="display: none" id="Codehighlighter1_200_1908_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_200_1908_Closed_Text.style.display='none'; Codehighlighter1_200_1908_Open_Image.style.display='inline'; Codehighlighter1_200_1908_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;CSVToArray:</span><span style="color: #0000ff">function</span><span style="color: #000000">(strData,&nbsp;strDelimiter)</span><span style="border-bottom: #808080 1px solid; border-left: #808080 1px solid; background-color: #ffffff; display: none; border-top: #808080 1px solid; border-right: #808080 1px solid" id="Codehighlighter1_200_1908_Closed_Text"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_200_1908_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Check&nbsp;to&nbsp;see&nbsp;if&nbsp;the&nbsp;delimiter&nbsp;is&nbsp;defined.&nbsp;If&nbsp;not,</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;then&nbsp;default&nbsp;to&nbsp;comma.</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strDelimiter&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(strDelimiter&nbsp;</span><span style="color: #000000">||</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">,</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Create&nbsp;a&nbsp;regular&nbsp;expression&nbsp;to&nbsp;parse&nbsp;the&nbsp;CSV&nbsp;values.</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">var</span><span style="color: #000000">&nbsp;objPattern&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;RegExp(<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Delimiters.</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">(\\</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;strDelimiter&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">|\\r?\\n|\\r|^)</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Quoted&nbsp;fields.</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">(?:\</span><span style="color: #000000">"</span><span style="color: #000000">([</span><span style="color: #000000">^</span><span style="color: #000000">\</span><span style="color: #000000">"</span><span style="color: #000000">]*(?:\</span><span style="color: #000000">"</span><span style="color: #000000">\</span><span style="color: #000000">"</span><span style="color: #000000">[^\</span><span style="color: #000000">"</span><span style="color: #000000">]</span><span style="color: #000000">*</span><span style="color: #000000">)</span><span style="color: #000000">*</span><span style="color: #000000">)\</span><span style="color: #000000">"</span><span style="color: #000000">|</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Standard&nbsp;fields.</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">([^\</span><span style="color: #000000">"</span><span style="color: #000000">\\</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;+&nbsp;strDelimiter&nbsp;+&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">\\r\\n]</span><span style="color: #000000">*</span><span style="color: #000000">))</span><span style="color: #000000">"</span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">gi</span><span style="color: #000000">"</span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Create&nbsp;an&nbsp;array&nbsp;to&nbsp;hold&nbsp;our&nbsp;data.&nbsp;Give&nbsp;the&nbsp;array<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;a&nbsp;default&nbsp;empty&nbsp;first&nbsp;row.<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;arrData&nbsp;=&nbsp;[[]];<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Create&nbsp;an&nbsp;array&nbsp;to&nbsp;hold&nbsp;our&nbsp;individual&nbsp;pattern<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;matching&nbsp;groups.<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;arrMatches&nbsp;=&nbsp;null;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Keep&nbsp;looping&nbsp;over&nbsp;the&nbsp;regular&nbsp;expression&nbsp;matches<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;until&nbsp;we&nbsp;can&nbsp;no&nbsp;longer&nbsp;find&nbsp;a&nbsp;match.<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(arrMatches&nbsp;=&nbsp;objPattern.exec(&nbsp;strData&nbsp;)){<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Get&nbsp;the&nbsp;delimiter&nbsp;that&nbsp;was&nbsp;found.<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;strMatchedDelimiter&nbsp;=&nbsp;arrMatches[&nbsp;1&nbsp;];<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Check&nbsp;to&nbsp;see&nbsp;if&nbsp;the&nbsp;given&nbsp;delimiter&nbsp;has&nbsp;a&nbsp;length<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;(is&nbsp;not&nbsp;the&nbsp;start&nbsp;of&nbsp;string)&nbsp;and&nbsp;if&nbsp;it&nbsp;matches<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;field&nbsp;delimiter.&nbsp;If&nbsp;id&nbsp;does&nbsp;not,&nbsp;then&nbsp;we&nbsp;know<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;that&nbsp;this&nbsp;delimiter&nbsp;is&nbsp;a&nbsp;row&nbsp;delimiter.<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strMatchedDelimiter.length&nbsp;&amp;&amp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(strMatchedDelimiter&nbsp;!=&nbsp;strDelimiter)<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;){<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Since&nbsp;we&nbsp;have&nbsp;reached&nbsp;a&nbsp;new&nbsp;row&nbsp;of&nbsp;data,<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;add&nbsp;an&nbsp;empty&nbsp;row&nbsp;to&nbsp;our&nbsp;data&nbsp;array.<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arrData.push(&nbsp;[]&nbsp;);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;Now&nbsp;that&nbsp;we&nbsp;have&nbsp;our&nbsp;delimiter&nbsp;out&nbsp;of&nbsp;the&nbsp;way,<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;let's&nbsp;check&nbsp;to&nbsp;see&nbsp;which&nbsp;kind&nbsp;of&nbsp;value&nbsp;we<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;captured&nbsp;(quoted&nbsp;or&nbsp;unquoted).<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(arrMatches[&nbsp;2&nbsp;]){<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;We&nbsp;found&nbsp;a&nbsp;quoted&nbsp;value.&nbsp;When&nbsp;we&nbsp;capture<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;this&nbsp;value,&nbsp;unescape&nbsp;any&nbsp;double&nbsp;quotes.<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;strMatchedValue&nbsp;=&nbsp;arrMatches[&nbsp;2&nbsp;].replace(<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;RegExp(&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">\</span><span style="color: #000000">"</span><span style="color: #000000">\</span><span style="color: #000000">""</span><span style="color: #000000">,&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">g</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;),<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">\</span><span style="color: #000000">""</span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img id="Codehighlighter1_1915_2001_Open_Image" onclick="this.style.display='none'; Codehighlighter1_1915_2001_Open_Text.style.display='none'; Codehighlighter1_1915_2001_Closed_Image.style.display='inline'; Codehighlighter1_1915_2001_Closed_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" /><img style="display: none" id="Codehighlighter1_1915_2001_Closed_Image" onclick="this.style.display='none'; Codehighlighter1_1915_2001_Closed_Text.style.display='none'; Codehighlighter1_1915_2001_Open_Image.style.display='inline'; Codehighlighter1_1915_2001_Open_Text.style.display='inline';" alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">else</span><span style="color: #000000">&nbsp;</span><span id="Codehighlighter1_1915_2001_Open_Text"><span style="color: #000000">{<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;We&nbsp;found&nbsp;a&nbsp;non-quoted&nbsp;value.</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">var</span><span style="color: #000000">&nbsp;strMatchedValue&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;arrMatches[&nbsp;</span><span style="color: #000000">3</span><span style="color: #000000">&nbsp;];<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Now&nbsp;that&nbsp;we&nbsp;have&nbsp;our&nbsp;value&nbsp;string,&nbsp;let's&nbsp;add</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;it&nbsp;to&nbsp;the&nbsp;data&nbsp;array.</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arrData[&nbsp;arrData.length&nbsp;</span><span style="color: #000000">-</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">&nbsp;].push(&nbsp;strMatchedValue&nbsp;);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">&nbsp;Return&nbsp;the&nbsp;parsed&nbsp;data.</span><span style="color: #008000"><br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">(&nbsp;arrData&nbsp;);<br />
<img alt="" align="top" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<img src ="http://www.blogjava.net/yuxh/aggbug/339669.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2010-12-03 09:06 <a href="http://www.blogjava.net/yuxh/archive/2010/12/03/339669.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Puzzlers（三-二 循环）</title><link>http://www.blogjava.net/yuxh/archive/2010/11/15/338121.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Mon, 15 Nov 2010 11:59:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2010/11/15/338121.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/338121.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2010/11/15/338121.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/338121.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/338121.html</trackback:ping><description><![CDATA[<p>31 <br>while (i != 0)<br>&nbsp;&nbsp;&nbsp; i &gt;&gt;&gt;= 1; //无符号右移，不管正负左边都是补0<br>为了表达式合法，这里的i必须是整型(<tt>byte</tt>, <tt>char</tt>, <tt>short</tt>, <tt>int</tt>, or <tt>long</tt>)。谜题的关键在于<tt>&gt;&gt;&gt;=</tt> 是一个复合赋值操作符，不幸的是复合赋值操作符会默默的做<span class="docEmphasis">narrowing primitive conversions，即从一个数据类型转换为一个更小的数据类型。<span class="docEmphStrong">Narrowing primitive conversions can lose information about the magnitude or precision of numeric values</span>。为了使问题更具体，假设这样定义：<br>short i = -1; 因为初始值i (<tt>(short)0xffff</tt>) 非零，循环执行。第一步位移会把i提升为int。<tt>short</tt>, <tt>byte</tt>, or <tt>char</tt>类型的操作数都会做这样的操作。这是<span class="docEmphasis">widening</span> primitive conversion，没有信息丢失。这种提升有符号扩展，因此结果是int值<tt>0xffffffff</tt>。无符号右移一位产生int值<tt>0x7fffffff</tt>。为了把int值存回short变量，Java执行了可怕的narrowing primitive conversion,即简单去掉高十六位。这样又变回了<tt>(short)0xffff</tt>。如果定义类似<tt>short</tt> or <tt>byte</tt>型的负数，都会得到类似结果。你如果定义的是char话，则不会无限循环，因为char值非负，位移之前的宽扩展不会做符号扩展。<br><br>总结：<span style="color: red">不要在<tt>short</tt>, <tt>byte</tt>, or <tt>char</tt>变量上使用复合赋值操作符</span>。这种表达式进行混合类型计算，非常容易混淆。更糟糕的是隐含的窄映射会丢掉信息。<br><br>32 <br>while (i &lt;= j &amp;&amp; j &lt;= i &amp;&amp; i != j) {}<br><tt>i &lt;= j</tt> and <tt>j &lt;= i</tt>, surely <tt>i</tt> must equal <tt>j</tt>？对于实数来说是这样的。他非常重要，有个名称：The ≤ relation on the real numbers is said to be <span class="docEmphasis">antisymmetric。Java's <tt>&lt;=</tt> operator used to be antisymmetric before release 5.0, but no longer.Java 5之前数据比较符号(<tt>&lt;, &lt;=</tt>, <tt>&gt;</tt>, and <tt>&gt;=</tt>) 需要两边的操作数必须为基础类型(<tt>byte</tt>, <tt>char</tt>, <tt>short</tt>, <tt>int</tt>, <tt>long</tt>, <tt>float</tt>, or <tt>double).在Java 5变为两边操作数为凡是可转变为基础类型的类型。java 5引入autoboxing and auto-unboxing 。The boxed numeric types are <tt>Byte</tt>, <tt>Character</tt>, <tt>Short</tt>, <tt>Integer</tt>, <tt>Long</tt>, <tt>Float</tt>, and <tt>Double。具体点，让上面进入无限循环：<br></tt></tt></span>Integer i = new Integer(0);<br>Integer j = new Integer(0);<br> (<tt>i &lt;= j</tt> and <tt>j &lt;= i</tt>) perform <span class="docEmphasis">unboxing conversions</span> on <tt>i</tt> and <tt>j</tt> and compare the resulting <tt>int</tt> values numerically。i和j表示0，所以表达式为true。<tt>i != j</tt>比较的是对象引用，也为true。很奇怪规范没有把等号改为比较值。原因很简单：兼容性。当一种语言广泛应用的时候，不能破坏已存在的规范来改变程序的行为。System.out.println(new Integer(0) == new Integer(0));总是输出false，所以必须保留。当一个是boxed numeric 类型，另一个是基本类型的时候可以值比较。因为java 5之前这是非法的，具体点：<br>System.out.println(new Integer(0) == 0); //之前的版本非法，Java 5输出True<br>总结：<span style="color: red">当两边的操作数是boxed numeric类型的时候，数字比较符和等于符号是根本不同的：数字比较符是值比较，等号比较的是对象引用</span>。<br><br>33 <br>while (i != 0 &amp;&amp; i == -i) {}<br>有负号表示i一定是数字，NaN不行，因为他不等于任何数。事实上，没有实数可以出现这种情况。但Java的数字类型并没有完美表达实数。浮点数由一个符号位，一个有效数字（尾数），一个指数构成。浮点数只有0才会和自己的负数相等，所以i肯定是整数。有符号整数用的是二进制补码计算：取反加一。补码的一大优势是用一个唯一的数来表示0。然而有一个对应的缺点：本来可表达偶数个值，现在用一个表达了0，剩下奇数个来表示正负数，意味着正数和负数的数量不一样。比如int值，他的<tt>Integer.MIN_VALUE</tt>（<tt>-2</tt><sup>31</sup>）。十六进制表达<tt>0x8000000</tt>。通过补码计算可知他的负数仍然不变。对他取负数是溢出了的，不过Java在整数计算中忽略了溢出。<br>总结：Java使用二进制补码，是不对称的。有符号整数(<tt>int</tt>, <tt>long</tt>, <tt>byte</tt>, and <tt>short</tt>) 负数值比整数值多一个。<br><br>34<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; final int START = 2000000000;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int count = 0;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (float f = START; f &lt; START + 50; f++)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count++;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(count);<br>注意循环变量是float。回忆谜题28 ，明显f++没有任何作用。f的初始化值接近<tt>Integer.MAX_VALUE</tt>，因此需要31位来准确表达，但是float类型只提供了24位精度。增加这样大的一个float值不会改变值。看起来会死循环？运行程序会发现，输出0。循环中f和<tt>(float)(START + 50)做比较。但int和float比较的时候，自动把int先提示为float。不幸的是三个会引起精度丢失的宽基本类型转换的其中之一（另外两个是long到float，long到double）。f的初始值巨大，加50再转换为float和直接把f转换为float是一样的效果，即<tt>(float)2000000000 == 2000000050，所以<tt>f &lt; START + 50</tt> 失败。只要把float改为int即可修正。<br></tt></tt>&nbsp;&nbsp;&nbsp;&nbsp; 没有计算器，你怎么知道 2,000,000,050 和float表示2,000,000,000一样？……<br>The moral of this puzzle is simple: <span style="color: red" class="docEmphStrong">Do not use floating-point loop indices</span>, because it can lead to unpredictable behavior. If you need a floating-point value in the body of a loop, take the <tt>int</tt> or <tt>long</tt> loop index and convert it to a <tt>float</tt> or <tt>double</tt>. <span class="docEmphStrong">You may lose precision when converting an <tt>int</tt> or <tt>long</tt> to a <tt>float</tt> or a <tt>long</tt> to a <tt>double</tt></span>, but at least it will not affect the loop itself. <span class="docEmphStrong">When you use floating-point, use <tt>double</tt> rather than <tt>float</tt></span> unless you are certain that <tt>float</tt> provides enough precision <span class="docEmphasis">and</span> you have a compelling performance need to use <tt>float</tt>. The times when it's appropriate to use <tt>float</tt> rather than <tt>double</tt> are few and far between。<br></span></p> <p><span class="docEmphasis">35 <br></span><span class="docEmphasis">下面程序模拟一个简单的时钟<br>int minutes = 0; <br>for (int ms = 0; ms &lt; 60*60*1000; ms++) <br>&nbsp; if (ms %&nbsp; 60*1000 == 0) <br>&nbsp;&nbsp;&nbsp;&nbsp; minutes++; <br>&nbsp;</span><span class="docEmphasis">System.out.println(minutes); </span><span class="docEmphasis"><br>结果是<tt>60000，问题在于布尔表达式ms % 60*1000 == 0，最简单的修改方法是：if (ms % (60 * 1000) == 0) <br>更好的方法是<font color="#ff0000">用合适命名的常量代替魔力数字</font>：</tt></span></p> <p><span class="docEmphasis"><tt></tt></span>private static final int MS_PER_HOUR = 60 * 60 * 1000; <br>private static final int MS_PER_MINUTE = 60 * 1000; <br>public static void main(String[] args) {<br>&nbsp;&nbsp; int minutes = 0; <br>&nbsp;&nbsp; for (int ms = 0; ms &lt; MS_PER_HOUR; ms++) <br>&nbsp;&nbsp;&nbsp;&nbsp; if (ms % MS_PER_MINUTE == 0) <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minutes++;<br>&nbsp;&nbsp;&nbsp; System.out.println(minutes); <br>} <span class="docEmphasis"><br><font color="#ff0000">绝不要用空格来分组；使用括号来决定优先级</font></p></span><img src ="http://www.blogjava.net/yuxh/aggbug/338121.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2010-11-15 19:59 <a href="http://www.blogjava.net/yuxh/archive/2010/11/15/338121.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Puzzlers（三-一 循环）</title><link>http://www.blogjava.net/yuxh/archive/2010/11/15/336547.html</link><dc:creator>yuxh</dc:creator><author>yuxh</author><pubDate>Mon, 15 Nov 2010 08:39:00 GMT</pubDate><guid>http://www.blogjava.net/yuxh/archive/2010/11/15/336547.html</guid><wfw:comment>http://www.blogjava.net/yuxh/comments/336547.html</wfw:comment><comments>http://www.blogjava.net/yuxh/archive/2010/11/15/336547.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuxh/comments/commentRss/336547.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuxh/services/trackbacks/336547.html</trackback:ping><description><![CDATA[<span style="color: #000000">24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp; for (byte b = Byte.MIN_VALUE; b &lt; Byte.MAX_VALUE; b++) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (b == 0x90)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("Joy!");<br />
&nbsp;&nbsp;&nbsp; }<br />
<tt>Ox90</tt> 超过了byte的取值范围<font face="Courier New">-128到127。byte和int比较是一种混合类型比较。考虑个表达式<tt>((byte)0x90 == 0x90)得到的是false。byte和int做比较的时候，Java先对byte进行了widening primitive conversion 再比较两个int值。因为byte是有符号类型，转变做了符号扩展，把负的byte值转换为相应的int值。这个例子中(byte)0x90被转变为-112，当然不等于int值 <tt>0x90</tt>或者说+144。混合比较总让人迷惑，因为总是强迫系统去提升一个操作数来和另一种类型匹配。有几种方式可避免混合比较。可以把int映射为byte，之后比较两个byte值： <br />
if (b == (byte)0x90)<br />
&nbsp;&nbsp;&nbsp; System.out.println("Joy!");<br />
另外，可用mask抑制符号扩展，把byte转换为int，之后比较两个int值：<br />
if ((b &amp; 0xff) == 0x90)<br />
&nbsp;&nbsp;&nbsp; System.out.println("Joy!");<br />
但最好的方法是把常量值移出循环放到常量声明中。<br />
<span class="docEmphStrong">&nbsp;&nbsp;&nbsp; private static final byte TARGET = 0x90; // Broken!</span><br />
&nbsp;&nbsp;&nbsp; public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (byte b = Byte.MIN_VALUE; b &lt; Byte.MAX_VALUE; b++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (b == TARGET)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("Joy!");<br />
&nbsp;&nbsp;&nbsp; }<br />
不幸的是，上面编译通不过：<tt>0x90</tt>对于byte类型来说不是一个有效值。这样修改即可：<br />
private static final byte TARGET = <span class="docEmphStrong">(byte)</span>0x90;<br />
<p class="docText">To summarize: <span class="docEmphStrong">Avoid mixed-type comparisons, because they are inherently confusing</span> (<a class="docLink" href="ch02lev1sec5.html#ch02lev1sec5">Puzzle 5</a>). To help achieve this goal, <span class="docEmphStrong">use declared constants in place of "magic numbers." </span>You already knew that this was a good idea; it documents the meanings of constants, centralizes their definitions, and eliminates duplicate definitions.现在你知道他还可以强制你为每一个常量定义适用的类型，避免一种混合类型比较的来源。</p>
<p class="docText">25 <br />
</span<br />
<font color="#000000">int j = 0;<br />
for (int i = 0; i &lt; 100; i++)<br />
&nbsp; j = j++;<br />
System.out.println(j); //</font><font color="#000000">打印出的是0<span></p>
</font></tt></font>
<p>问题出在 j = j++; 等同于下列操作：</p>
<p>int tmp = j; j = j + 1; j = tmp; <br />
这次的教训和难题7一样：<font color="#ff0000">在一个表达式中不要给同一个变量赋值超过一次。</font></p>
<p><font color="#000000">26</font></p>
<p><font color="#000000">public static final int END = Integer.MAX_VALUE;<br />
public static final int START = END - 100;<br />
public static void main(String[] args) {<br />
&nbsp;&nbsp;&nbsp; int count = 0;<br />
&nbsp;&nbsp;&nbsp; for (int i = START; i &lt;= END; i++)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count++;<br />
&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(count);<br />
}<br />
看起来像100，再仔细看循环是小于等于，应该是101？结果是程序没有输出任何值，陷入一个死循环。问题出在<tt>Integer.MAX_VALUE，当继续增加的时候，他悄悄变为<tt>Integer.MIN_VALUE。如果你需要循环int值边界，最好用long变量做索引：<br />
for (long i = START; i &lt;= END; i++)&nbsp; //输出101<br />
<font color="#ff0000">教训是：<tt>int</tt>s are not integers。无论何时用基本类型，注意边界值。上溢或下溢会出现什么情况？一般来说最好用大一点的类型（基本类型是<tt>byte</tt>, <tt>char</tt>, <tt>short</tt>, <tt>int</tt>, and <tt>long</tt>）。</font>也可以不用long：</tt></tt></font></p>
<p><font color="#000000">int i = START; <br />
do { <br />
&nbsp; count++; <br />
} while (i++ != END); <br />
考虑到清晰和简单，总是用long索引，除了一种特殊情况：如果要遍历所有int值，这样用int索引的话会快两倍。<br />
一个循环四十亿int值，调用方法的常规用法：</font><font color="#ff0000"></p>
<pre><font color="#000000">// Apply the function f to all four billion int values
int i = Integer.MIN_VALUE;
do {
f(i);
} while (i++ != Integer.MAX_VALUE);
</font></pre>
<p><span style="color: #000000">27&nbsp; 位移<br />
<font color="#ff0000"><span style="color: #000000"><font style="color: #000000" color="#ff0000">记住java是使用二进制补码计算，在任何有符号基本类型中(<tt>byte</tt>, <tt>short</tt>, <tt>int</tt>, or <tt>long</tt>)都是用所有位置1来表示-1。 <br />
</font><font color="#ff0000"><span style="color: #000000"><font color="#ff0000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #000000"><font style="color: #000000" color="#ff0000">int i = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (-1 &lt;&lt; i != 0)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //左位移<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(i);<br />
</font>int型的-1用<tt>0xffffffff</tt> 表示。不断左移，右边由0补位。移位32次，变为全0，跳出循环打印32？实际上程序会死循环。问题出在-1&lt;&lt;32不等于0而是等于-1，因为位<span style="color: #ff0000">移符号只用右边操作数的低五位作为移动距离</span>，如果左操作数是long的话用六位。三个位移操作符：&lt;&lt;,&gt;&gt;,&gt;&gt;&gt;都是这样。移动距离总是0到31，左边操作数是long的话0到63。位移距离用32取模，左边是long则用64取模。给int值位移32位或给long值位移64位只会返回本身。所以不可能用位移完全移除一个数据。幸运的是，有一个简单的办法解决这个问题。保存上一次的位移结果，每一次迭代多移动一位。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int distance = 0;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int val = -1; val != 0; val &lt;&lt;= 1)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; distance++;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(distance);<br />
修改后的程序说明了一个原则：<span style="color: #ff0000">位移距离如果可能的话，用常量</span>。<br />
另外一个问题，许多程序员认为右移一个负的移动距离，就和左移一样，反之亦然。事实上不是这样，左移是左移，右移就是右移。负数距离只留下低五位（long留六位），其余的置0就变为了正数距离。比如，左移一个int值-1的距离，实际上是左移31位。<br />
<br />
28 无穷的表示<br />
for (int i = start; i &lt;= start + 1; i++) {<br />
}<br />
看起来循环两次就会结束，如果这样定义呢：<br />
int start = Integer.MAX_VALUE - 1;//死循环<br />
while (i == i + 1) {<br />
}<br />
这个不可能死循环？如果i是无穷呢？Java采用IEEE 754浮点数算术，用double或float来表示无穷。所以可以用任何浮点数计算表达式得出无穷来初始化i。比如：double i = 1.0 / 0.0;<br />
更好的是可以利用标准库提供的常量:double i = Double.POSITIVE_INFINITY;<br />
事实上，根本用不着用无穷初始化i来引起死循环。只要足够大的浮点数就够了：double i = 1.0e40;<br />
这是因为浮点数越大，他的值和下一个数的值距离也就越大。distribution of floating-point values is a consequence of their representation with a fixed number of <u>significant</u> bits. 给足够大的浮点数加一不会改变值，因为他不能填充这个数和下一个数之间的距离。浮点数操作返回最接近准确数学结果的浮点值。一旦两个相邻浮点值之间的距离大于2，加1就不会有效果。float类型来说，超过2<sup>25</sup>（或33,554,432）再加1就无效；对double来说超过2<sup>54</sup>（接近1.8 x 10<sup>16</sup>）再加1就无效。<br />
&nbsp;&nbsp;&nbsp;&nbsp; 相邻浮点数之间的距离称为ulp（unit in the last place的缩写）。在Java 5里 <tt>Math.ulp方法被引入来计算float或double值的ulp。</tt></span></font></span></font></span></font></span></p>
<p><span style="color: #000000"><font color="#ff0000"><span style="color: #000000"><font color="#ff0000"><span style="color: #000000"><font color="#ff0000"><span style="color: #000000"><tt>总结：<font color="#ff0000">不可能用float或double来表示无穷。另外，在一个大的浮点数上加一个小的浮点数，值不会改变。有点不合常理，实数并不是这样。记住二进制浮点数计算只是近似于实数计算。</font></tt></span></font></span></font></span></font></span></p>
<p></font><font color="#ff0000"><span style="color: #000000"><span style="color: #000000"><span style="color: #000000"><span style="color: #000000"><tt>29 NaN</tt></span></span></span></span></font></span></span></p>
<p>while (i != i) { } <br />
IEEE 754 浮点数计算保留了一个特殊值来来表示不是数字的数量。NaN是浮点计算不能很好定义的数，比如<tt>0.0 / 0.0。规范定义<font color="#ff0000">NaN不等于任何数包括自己</font>。因此double i = 0.0 / 0.0; 可让开始的等式不成立。也有标准库定义的常量：</tt>double i = Double.NaN; 如果一个或多个操作数为NaN，那么浮点数计算就会等于NaN。</p>
<p>总结：float和doule存在特殊的值NaN，小心处理。</p>
<p>30<br />
while (i != i + 0) { } 这一次不能使用float或者double。<br />
<tt>+操作符除了数字，就只能处理String。+操作符会被重载：对于String类型，他做的是连接操作。如果操作数有非String类型，会先做转换变为String之后再做连接。i一般用作数字，要是对String型变量这么命名容易引起误解。</tt></p>
<p><tt>总结：<font color="#ff0000">操作符重载非常容易误导人。好的变量名，方法名，类名和好的注释对于程序的可读性一样重要。</font></tt></p>
<img src ="http://www.blogjava.net/yuxh/aggbug/336547.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuxh/" target="_blank">yuxh</a> 2010-11-15 16:39 <a href="http://www.blogjava.net/yuxh/archive/2010/11/15/336547.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>