﻿<?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-java fans</title><link>http://www.blogjava.net/jlin/</link><description /><language>zh-cn</language><lastBuildDate>Wed, 29 Apr 2026 18:47:34 GMT</lastBuildDate><pubDate>Wed, 29 Apr 2026 18:47:34 GMT</pubDate><ttl>60</ttl><item><title>excel中如何将时间戳转换为日期格式</title><link>http://www.blogjava.net/jlin/archive/2019/03/08/433666.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Fri, 08 Mar 2019 05:58:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2019/03/08/433666.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433666.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2019/03/08/433666.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433666.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433666.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #fefef2;">从linux系统中获取的时间戳信息通常为ms，将其转换的公式为：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #fefef2;">=TEXT((C4/1000+8*3600)/86400+70*365+19,"yyyy-mm-dd hh:mm:ss")</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #fefef2;">其中C4单元格所存的数据为ms因此需要除以1000</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #fefef2;">转换后的结果如下：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5; font-size: 13px; font-family: Verdana, Arial, Helvetica, sans-serif; background-color: #fefef2;"><img src="https://images2015.cnblogs.com/blog/880406/201609/880406-20160913135210648-7424355.png" alt="" style="margin: 0px; padding: 0px; border: 0px; max-width: 900px; height: auto;" /></p><img src ="http://www.blogjava.net/jlin/aggbug/433666.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2019-03-08 13:58 <a href="http://www.blogjava.net/jlin/archive/2019/03/08/433666.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.lang.ClassCastException 两个一样的类不能强转</title><link>http://www.blogjava.net/jlin/archive/2019/01/30/433626.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Wed, 30 Jan 2019 03:30:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2019/01/30/433626.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433626.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2019/01/30/433626.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433626.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433626.html</trackback:ping><description><![CDATA[<div>系统报错： java.lang.ClassCastException: com.entity.Job cannot be cast to com.entity.Job<br /><br />spring boot 项目引入了 spring的devtools 经常会产生这个问题&nbsp; ，当把这个引入取消就不会出现了</div><div></div><div>&nbsp;<span style="white-space:pre">	</span>&lt;dependency&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &lt;/dependency&gt;&nbsp;</div><div></div><div></div><img src ="http://www.blogjava.net/jlin/aggbug/433626.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2019-01-30 11:30 <a href="http://www.blogjava.net/jlin/archive/2019/01/30/433626.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>记录一次kafka-manager1.3.3.18 Consumers is not display with kafka2.1.0 version</title><link>http://www.blogjava.net/jlin/archive/2018/12/13/433545.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Thu, 13 Dec 2018 07:36:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2018/12/13/433545.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433545.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2018/12/13/433545.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433545.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433545.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;使用kafka 2.1.0 ,然后用最新的kafka-manager&nbsp;1.3.3.18来管理kafka, 然后写了一个生产者和消费者程序，程序运行后，死活显示不出来程序运行后，消费者的group死活显示不出来。生产者代码如下：package com.kafka.producer;import org.apache.commons.lang3.exception.Excepti...&nbsp;&nbsp;<a href='http://www.blogjava.net/jlin/archive/2018/12/13/433545.html'>阅读全文</a><img src ="http://www.blogjava.net/jlin/aggbug/433545.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2018-12-13 15:36 <a href="http://www.blogjava.net/jlin/archive/2018/12/13/433545.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>centos7:安装node和npm</title><link>http://www.blogjava.net/jlin/archive/2018/12/12/433544.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Wed, 12 Dec 2018 02:29:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2018/12/12/433544.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433544.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2018/12/12/433544.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433544.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433544.html</trackback:ping><description><![CDATA[<div>通过安装包安装，可以使用<br /><br />先下载安装包到 /usr/local路径下<br /><br />wget https://npm.taobao.org/mirrors/node/v8.0.0/node-v8.0.0-linux-x64.tar.xz<br /><br />下载完成后解压<br />tar -xvf&nbsp; node-v8.0.0-linux-x64.tar.xz<br />重命名为node<br />mv node-v8.1.4-linux-x64 node<br /><br />配置环境变量<br />vim /etc/profile<br />在文件的最后添加<br />#set for nodejs &nbsp;<br />export NODE_HOME=/usr/local/node &nbsp;<br />export PATH=$NODE_HOME/bin:$PATH<br />保存退出后执行更新命令<br />source /etc/profile<br />如果不生效，重启系统就可以<br />检测node和npm是否安装成功<br />node -v<br />npm -v</div><img src ="http://www.blogjava.net/jlin/aggbug/433544.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2018-12-12 10:29 <a href="http://www.blogjava.net/jlin/archive/2018/12/12/433544.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在java中写出完美的单例模式（转）</title><link>http://www.blogjava.net/jlin/archive/2018/11/27/433525.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Tue, 27 Nov 2018 14:51:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2018/11/27/433525.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433525.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2018/11/27/433525.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433525.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433525.html</trackback:ping><description><![CDATA[<div id="cnblogs_post_body" style="margin-bottom: 20px; word-break: break-word;"><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">1. 前言</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">单例(Singleton)应该是开发者们最熟悉的设计模式了，并且好像也是最容易实现的&#8212;&#8212;基本上每个开发者都能够随手写出&#8212;&#8212;但是，真的是这样吗？</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">作为一个Java开发者，也许你觉得自己对单例模式的了解已经足够多了。我并不想危言耸听说一定还有你不知道的&#8212;&#8212;毕竟我自己的了解也的确有限，但究竟你自己了解的程度到底怎样呢？往下看，我们一起来聊聊看~</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">2. 什么是单例？</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">单例对象的类必须保证只有一个实例存在&#8212;&#8212;这是维基百科上对单例的定义，这也可以作为对意图实现单例模式的代码进行检验的标准。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">对单例的实现可以分为两大类&#8212;&#8212;懒汉式和饿汉式，他们的区别在于：</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><ul style="list-style: none; margin: 0px 0px 10px 30px; padding-left: 0px; font-size: 12px;"><li style="list-style-type: disc;"><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">懒汉式：指全局的单例实例在第一次被使用时构建。</p></li><li style="list-style-type: disc;"><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">饿汉式：指全局的单例实例在类装载时构建。</p></li></ul><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">从它们的区别也能看出来，日常我们使用的较多的应该是懒汉式的单例，毕竟按需加载才能做到资源的最大化利用嘛~</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">3. 懒汉式单例</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">先来看一下懒汉式单例的实现方式。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">3.1 简单版本</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">看最简单的写法Version 1：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> Version 1</span> <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;"> Single1 {     </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span><span style="line-height: 1.5 !important;"> Single1 instance;     </span><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span><span style="line-height: 1.5 !important;"> Single1 getInstance() {         </span><span style="color: #0000ff; line-height: 1.5 !important;">if</span> (instance == <span style="color: #0000ff; line-height: 1.5 !important;">null</span><span style="line-height: 1.5 !important;">) {             instance </span>= <span style="color: #0000ff; line-height: 1.5 !important;">new</span><span style="line-height: 1.5 !important;"> Single1();         }         </span><span style="color: #0000ff; line-height: 1.5 !important;">return</span><span style="line-height: 1.5 !important;"> instance;     } }</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">或者再进一步，把构造器改为私有的，这样能够防止被外部的类调用。</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> Version 1.1</span> <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;"> Single1 {     </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span><span style="line-height: 1.5 !important;"> Single1 instance;     </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span><span style="line-height: 1.5 !important;"> Single1() {}     </span><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span><span style="line-height: 1.5 !important;"> Single1 getInstance() {         </span><span style="color: #0000ff; line-height: 1.5 !important;">if</span> (instance == <span style="color: #0000ff; line-height: 1.5 !important;">null</span><span style="line-height: 1.5 !important;">) {             instance </span>= <span style="color: #0000ff; line-height: 1.5 !important;">new</span><span style="line-height: 1.5 !important;"> Single1();         }         </span><span style="color: #0000ff; line-height: 1.5 !important;">return</span><span style="line-height: 1.5 !important;"> instance;     } }</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">我仿佛记得当初学校的教科书就是这么教的？&#8212;&#8212; 每次获取instance之前先进行判断，如果instance为空就new一个出来，否则就直接返回已存在的instance。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">这种写法在大多数的时候也是没问题的。问题在于，当多线程工作的时候，如果有多个线程同时运行到if (instance == null)，都判断为null，那么两个线程就各自会创建一个实例&#8212;&#8212;这样一来，就不是单例了。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">3.2 synchronized版本</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">那既然可能会因为多线程导致问题，那么加上一个同步锁吧！</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">修改后的代码如下，相对于Version1.1，只是在方法签名上多加了一个synchronized：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> Version 2 </span> <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;"> Single2 {     </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span><span style="line-height: 1.5 !important;"> Single2 instance;     </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span><span style="line-height: 1.5 !important;"> Single2() {}     </span><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">synchronized</span><span style="line-height: 1.5 !important;"> Single2 getInstance() {         </span><span style="color: #0000ff; line-height: 1.5 !important;">if</span> (instance == <span style="color: #0000ff; line-height: 1.5 !important;">null</span><span style="line-height: 1.5 !important;">) {             instance </span>= <span style="color: #0000ff; line-height: 1.5 !important;">new</span><span style="line-height: 1.5 !important;"> Single2();         }         </span><span style="color: #0000ff; line-height: 1.5 !important;">return</span><span style="line-height: 1.5 !important;"> instance;     } }</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">OK，加上synchronized关键字之后，getInstance方法就会锁上了。如果有两个线程（T1、T2）同时执行到这个方法时，会有其中一个线程T1获得同步锁，得以继续执行，而另一个线程T2则需要等待，当第T1执行完毕getInstance之后（完成了null判断、对象创建、获得返回值之后），T2线程才会执行执行。&#8212;&#8212;所以这端代码也就避免了Version1中，可能出现因为多线程导致多个实例的情况。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">但是，这种写法也有一个问题：给gitInstance方法加锁，虽然会避免了可能会出现的多个实例问题，但是会强制除T1之外的所有线程等待，实际上会对程序的执行效率造成负面影响。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">3.3 双重检查（Double-Check）版本</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">Version2代码相对于Version1d代码的效率问题，其实是为了解决1%几率的问题，而使用了一个100%出现的防护盾。那有一个优化的思路，就是把100%出现的防护盾，也改为1%的几率出现，使之只出现在可能会导致多个实例出现的地方。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212;有没有这样的方法呢？当然是有的，改进后的代码Vsersion3如下：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> Version 3 </span> <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;"> Single3 {     </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span><span style="line-height: 1.5 !important;"> Single3 instance;     </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span><span style="line-height: 1.5 !important;"> Single3() {}     </span><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span><span style="line-height: 1.5 !important;"> Single3 getInstance() {         </span><span style="color: #0000ff; line-height: 1.5 !important;">if</span> (instance == <span style="color: #0000ff; line-height: 1.5 !important;">null</span><span style="line-height: 1.5 !important;">) {             </span><span style="color: #0000ff; line-height: 1.5 !important;">synchronized</span> (Single3.<span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;">) {                 </span><span style="color: #0000ff; line-height: 1.5 !important;">if</span> (instance == <span style="color: #0000ff; line-height: 1.5 !important;">null</span><span style="line-height: 1.5 !important;">) {                     instance </span>= <span style="color: #0000ff; line-height: 1.5 !important;">new</span><span style="line-height: 1.5 !important;"> Single3();                 }             }         }         </span><span style="color: #0000ff; line-height: 1.5 !important;">return</span><span style="line-height: 1.5 !important;"> instance;     } }</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">这个版本的代码看起来有点复杂，注意其中有两次if (instance == null)的判断，这个叫做『双重检查 Double-Check』。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><ul style="list-style: none; margin: 0px 0px 10px 30px; padding-left: 0px; font-size: 12px;"><li style="list-style-type: disc;"><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">第一个if (instance == null)，其实是为了解决Version2中的效率问题，只有instance为null的时候，才进入synchronized的代码段&#8212;&#8212;大大减少了几率。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p></li><li style="list-style-type: disc;"><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">第二个if (instance == null)，则是跟Version2一样，是为了防止可能出现多个实例的情况。</p></li></ul><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212; 这段代码看起来已经完美无瑕了。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212; 当然，只是『看起来』，还是有小概率出现问题的。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">这弄清楚为什么这里可能出现问题，首先，我们需要弄清楚几个概念：原子操作、指令重排。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">知识点：什么是原子操作？</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">简单来说，原子操作（atomic）就是不可分割的操作，在计算机中，就是指不会因为线程调度被打断的操作。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">比如，简单的赋值是一个原子操作：</p><div style="margin: 5px 0px; font-size: 12px !important;"><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;">m = 6; <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 这是个原子操作</span></pre></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">假如m原先的值为0，那么对于这个操作，要么执行成功m变成了6，要么是没执行m还是0，而不会出现诸如m=3这种中间态&#8212;&#8212;即使是在并发的线程中。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">而，声明并赋值就不是一个原子操作：</p><div style="margin: 5px 0px; font-size: 12px !important;"><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #0000ff; line-height: 1.5 !important;">int</span> n = 6; <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 这不是一个原子操作</span></pre></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">对于这个语句，至少有两个操作：</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#9312;声明一个变量n</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#9313;给n赋值为6</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212;这样就会有一个中间状态：变量n已经被声明了但是还没有被赋值的状态。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212;这样，在多线程中，由于线程执行顺序的不确定性，如果两个线程都使用m，就可能会导致不稳定的结果出现。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">知识点：什么是指令重排？</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">简单来说，就是计算机为了提高执行效率，会做的一些优化，在不影响最终结果的情况下，可能会对一些语句的执行顺序进行调整。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">比如，这一段代码：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #0000ff; line-height: 1.5 !important;">int</span> a ;   <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 语句1 </span> <span style="line-height: 1.5 !important;"> a </span>= 8 ;   <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 语句2</span>  <span style="color: #0000ff; line-height: 1.5 !important;">int</span> b = 9 ;     <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 语句3</span>  <span style="color: #0000ff; line-height: 1.5 !important;">int</span> c = a + b ; <span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 语句4</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">正常来说，对于顺序结构，执行的顺序是自上到下，也即1234。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">但是，由于指令重排的原因，因为不影响最终的结果，所以，实际执行的顺序可能会变成3124或者1324。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">由于语句3和4没有原子性的问题，语句3和语句4也可能会拆分成原子操作，再重排。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212;也就是说，对于非原子性的操作，在不影响最终结果的情况下，其拆分成的原子操作可能会被重新排列执行顺序。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">OK，了解了原子操作和指令重排的概念之后，我们再继续看Version3代码的问题。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">下面这段话直接从陈皓的文章(深入浅出单实例SINGLETON设计模式)中复制而来：</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">主要在于singleton = new Singleton()这句，这并非是一个原子操作，事实上在 JVM 中这句话大概做了下面 3 件事情。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">1. 给 singleton 分配内存</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">2. 调用 Singleton 的构造函数来初始化成员变量，形成实例</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">3. 将singleton对象指向分配的内存空间（执行完这步 singleton才是非 null 了）</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">但是在 JVM 的即时编译器中存在指令重排序的优化。也就是说上面的第二步和第三步的顺序是不能保证的，最终的执行顺序可能是 1-2-3 也可能是 1-3-2。如果是后者，则在 3 执行完毕、2 未执行之前，被线程二抢占了，这时 instance 已经是非 null 了（但却没有初始化），所以线程二会直接返回 instance，然后使用，然后顺理成章地报错。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">再稍微解释一下，就是说，由于有一个『instance已经不为null但是仍没有完成初始化』的中间状态，而这个时候，如果有其他线程刚好运行到第一层if (instance == null)这里，这里读取到的instance已经不为null了，所以就直接把这个中间状态的instance拿去用了，就会产生问题。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">这里的关键在于&#8212;&#8212;线程T1对instance的写操作没有完成，线程T2就执行了读操作。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">3.4 终极版本：volatile</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">对于Version3中可能出现的问题（当然这种概率已经非常小了，但毕竟还是有的嘛~），解决方案是：只需要给instance的声明加上volatile关键字即可，Version4版本：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> Version 4 </span>  <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;"> Single4 {      </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">volatile</span><span style="line-height: 1.5 !important;"> Single4 instance;      </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span><span style="line-height: 1.5 !important;"> Single4() {}      </span><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span><span style="line-height: 1.5 !important;"> Single4 getInstance() {          </span><span style="color: #0000ff; line-height: 1.5 !important;">if</span> (instance == <span style="color: #0000ff; line-height: 1.5 !important;">null</span><span style="line-height: 1.5 !important;">) {              </span><span style="color: #0000ff; line-height: 1.5 !important;">synchronized</span> (Single4.<span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;">) {                  </span><span style="color: #0000ff; line-height: 1.5 !important;">if</span> (instance == <span style="color: #0000ff; line-height: 1.5 !important;">null</span><span style="line-height: 1.5 !important;">) {                      instance </span>= <span style="color: #0000ff; line-height: 1.5 !important;">new</span><span style="line-height: 1.5 !important;"> Single4();                  }              }          }          </span><span style="color: #0000ff; line-height: 1.5 !important;">return</span><span style="line-height: 1.5 !important;"> instance;      }  }</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">volatile关键字的一个作用是禁止指令重排，把instance声明为volatile之后，对它的写操作就会有一个内存屏障（什么是内存屏障？），这样，在它的赋值完成之前，就不用会调用读操作。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">注意：volatile阻止的不singleton = new Singleton()这句话内部[1-2-3]的指令重排，而是保证了在一个写操作（[1-2-3]）完成之前，不会调用读操作（if (instance == null)）。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212;也就彻底防止了Version3中的问题发生。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212;好了，现在彻底没什么问题了吧？</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">好了，别紧张，的确没问题了。大名鼎鼎的EventBus中，其入口方法EventBus.getDefault()就是用这种方法来实现的。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">不过，非要挑点刺的话还是能挑出来的，就是这个写法有些复杂了，不够优雅、简洁。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">4. 饿汉式单例</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">下面再聊了解一下饿汉式的单例。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">如上所说，饿汉式单例是指：指全局的单例实例在类装载时构建的实现方式。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">由于类装载的过程是由类加载器（ClassLoader）来执行的，这个过程也是由JVM来保证同步的，所以这种方式先天就有一个优势&#8212;&#8212;能够免疫许多由多线程引起的问题。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">4.1 饿汉式单例的实现方式</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">饿汉式单例的实现如下：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;">饿汉式实现</span>  <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;"> SingleB {      </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">final</span> SingleB INSTANCE = <span style="color: #0000ff; line-height: 1.5 !important;">new</span><span style="line-height: 1.5 !important;"> SingleB();      </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span><span style="line-height: 1.5 !important;"> SingleB() {}      </span><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span><span style="line-height: 1.5 !important;"> SingleB getInstance() {          </span><span style="color: #0000ff; line-height: 1.5 !important;">return</span><span style="line-height: 1.5 !important;"> INSTANCE;      }  }</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">对于一个饿汉式单例的写法来说，它基本上是完美的了。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">所以它的缺点也就只是饿汉式单例本身的缺点所在了&#8212;&#8212;由于INSTANCE的初始化是在类加载时进行的，而类的加载是由ClassLoader来做的，所以开发者本来对于它初始化的时机就很难去准确把握：</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><ol style="padding-left: 40px;"><li style="list-style-type: decimal;"><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">可能由于初始化的太早，造成资源的浪费</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p></li><li style="list-style-type: decimal;"><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">如果初始化本身依赖于一些其他数据，那么也就很难保证其他数据会在它初始化之前准备好。</p></li></ol><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">当然，如果所需的单例占用的资源很少，并且也不依赖于其他数据，那么这种实现方式也是很好的。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">知识点：什么时候是类装载时？</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">前面提到了单例在类装载时被实例化，那究竟什么时候才是『类装载时』呢？</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">不严格的说，大致有这么几个条件会触发一个类被加载：</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">1. new一个对象时</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">2. 使用反射创建它的实例时</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">3. 子类被加载时，如果父类还没被加载，就先加载父类</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">4. jvm启动时执行的主类会首先被加载</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">5. 一些其他的实现方式</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">5.1 Effective Java 1 &#8212;&#8212; 静态内部类</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">《Effective Java》一书的第一版中推荐了一个中写法：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> Effective Java 第一版推荐写法</span>  <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;"> Singleton {      </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">class</span><span style="line-height: 1.5 !important;"> SingletonHolder {          </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">final</span> Singleton INSTANCE = <span style="color: #0000ff; line-height: 1.5 !important;">new</span><span style="line-height: 1.5 !important;"> Singleton();      }      </span><span style="color: #0000ff; line-height: 1.5 !important;">private</span><span style="line-height: 1.5 !important;"> Singleton (){}      </span><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">static</span> <span style="color: #0000ff; line-height: 1.5 !important;">final</span><span style="line-height: 1.5 !important;"> Singleton getInstance() {          </span><span style="color: #0000ff; line-height: 1.5 !important;">return</span><span style="line-height: 1.5 !important;"> SingletonHolder.INSTANCE;      }  }</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">这种写法非常巧妙：</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><ul style="list-style: none; margin: 0px 0px 10px 30px; padding-left: 0px; font-size: 12px;"><li style="list-style-type: disc;"><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">对于内部类SingletonHolder，它是一个饿汉式的单例实现，在SingletonHolder初始化的时候会由ClassLoader来保证同步，使INSTANCE是一个真&#183;单例。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p></li><li style="list-style-type: disc;"><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">同时，由于SingletonHolder是一个内部类，只在外部类的Singleton的getInstance()中被使用，所以它被加载的时机也就是在getInstance()方法第一次被调用的时候。</p></li></ul><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212;它利用了ClassLoader来保证了同步，同时又能让开发者控制类加载的时机。从内部看是一个饿汉式的单例，但是从外部看来，又的确是懒汉式的实现。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">简直是神乎其技。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">5.2 Effective Java 2 &#8212;&#8212; 枚举</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">你以为到这就算完了？不，并没有，因为厉害的大神又发现了其他的方法。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">《Effective Java》的作者在这本书的第二版又推荐了另外一种方法，来直接看代码：</p><div style="margin: 5px 0px; font-size: 12px !important;"><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div><pre style="margin-top: 0px; margin-bottom: 0px; white-space: pre-wrap; word-wrap: break-word; font-family: &quot;Courier New&quot; !important;"><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> Effective Java 第二版推荐写法</span>  <span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">enum</span><span style="line-height: 1.5 !important;"> SingleInstance {      INSTANCE;      </span><span style="color: #0000ff; line-height: 1.5 !important;">public</span> <span style="color: #0000ff; line-height: 1.5 !important;">void</span><span style="line-height: 1.5 !important;"> fun1() {           </span><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> do something</span> <span style="line-height: 1.5 !important;">     }  }     </span><span style="color: #008000; line-height: 1.5 !important;">//</span><span style="color: #008000; line-height: 1.5 !important;"> 使用</span> <span style="line-height: 1.5 !important;"> SingleInstance.INSTANCE.fun1();</span></pre><div style="margin-top: 5px;"><span style="padding-right: 5px; line-height: 1.5 !important;"><a title="复制代码" style="color: #1a8bc8; border: none !important;"><img src="https://common.cnblogs.com/images/copycode.gif" alt="复制代码" style="max-width: 900px; height: auto; border: none !important;" /></a></span></div></div><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">看到了么？这是一个枚举类型&#8230;&#8230;连class都不用了，极简。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">由于创建枚举实例的过程是线程安全的，所以这种写法也没有同步的问题。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">作者对这个方法的评价：</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">这种写法在功能上与共有域方法相近，但是它更简洁，无偿地提供了序列化机制，绝对防止对此实例化，即使是在面对复杂的序列化或者反射攻击的时候。虽然这中方法还没有广泛采用，但是单元素的枚举类型已经成为实现Singleton的最佳方法。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">枚举单例这种方法问世一些，许多分析文章都称它是实现单例的最完美方法&#8212;&#8212;写法超级简单，而且又能解决大部分的问题。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">不过我个人认为这种方法虽然很优秀，但是它仍然不是完美的&#8212;&#8212;比如，在需要继承的场景，它就不适用了。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">6. 总结</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">OK，看到这里，你还会觉得单例模式是最简单的设计模式了么？再回头看一下你之前代码中的单例实现，觉得是无懈可击的么？</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">可能我们在实际的开发中，对单例的实现并没有那么严格的要求。比如，我如果能保证所有的getInstance都是在一个线程的话，那其实第一种最简单的教科书方式就够用了。再比如，有时候，我的单例变成了多例也可能对程序没什么太大影响&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">但是，如果我们能了解更多其中的细节，那么如果哪天程序出了些问题，我们起码能多一个排查问题的点。早点解决问题，就能早点回家吃饭&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212; 还有，完美的方案是不存在，任何方式都会有一个『度』的问题。比如，你的觉得代码已经无懈可击了，但是因为你用的是JAVA语言，可能ClassLoader有些BUG啊&#8230;&#8230;你的代码谁运行在JVM上的，可能JVM本身有BUG啊&#8230;&#8230;你的代码运行在手机上，可能手机系统有问题啊&#8230;&#8230;你生活在这个宇宙里，可能宇宙本身有些BUG啊&#8230;&#8230;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">所以，尽力做到能做到的最好就行了。</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&nbsp;</p><p style="line-height: 1.5; margin-top: 10px; margin-bottom: 10px;">&#8212;&#8212; 感谢你花费了不少时间看到这里，但愿你没有觉得虚度。</p></div><div style="clear: both;"></div><div id="blog_post_info_block" style="margin-top: 20px;"><div id="BlogPostCategory" style="margin-bottom: 10px; color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;"></div><div id="EntryTag" style="color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff; margin-top: 0px !important;"></div><div id="blog_post_info" style="color: #4b4b4b; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; background-color: #ffffff;"></div></div><img src ="http://www.blogjava.net/jlin/aggbug/433525.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2018-11-27 22:51 <a href="http://www.blogjava.net/jlin/archive/2018/11/27/433525.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>@RequestParam与@PathVariable的区别（转）</title><link>http://www.blogjava.net/jlin/archive/2018/08/22/433344.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Wed, 22 Aug 2018 03:05:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2018/08/22/433344.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433344.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2018/08/22/433344.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433344.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433344.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">在<a title="Java EE知识库" href="http://lib.csdn.net/base/javaee" target="_blank" style="margin: 0px; padding: 0px; color: #000000;">spring</a>&nbsp;MVC中，两者的作用都是将request里的参数的值绑定到contorl里的方法参数里的，区别在于，URL写法不同。</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">使用@RequestParam时，URL是这样的：http://host:port/path?参数名=参数值<br style="margin: 0px; padding: 0px;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">使用@PathVariable时，URL是这样的：http://host:port/path/参数值<br style="margin: 0px; padding: 0px;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">例如：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">&nbsp;</p><div bg_java"="" style="word-break: break-word; background-color: #ffffff;"><div style="margin: 0px;"><div style="margin: 0px;"><strong style="margin: 0px; padding: 0px;">[java]</strong>&nbsp;<a title="view plain" href="http://blog.csdn.net/guge907/article/details/44923983#" target="_blank">view plain</a><span data-mod="popu_168" style="margin: 0px; padding: 0px;"><span data-mod="popu_168" style="margin: 0px; padding: 0px;">&nbsp;<a title="copy" href="http://blog.csdn.net/guge907/article/details/44923983#" target="_blank">copy</a></span></span><div style="margin: 0px;">&nbsp;</div></div></div><ol start="1" style="padding-left: 40px;"><li style="list-style-type: decimal; line-height: 1.6;">@RequestMapping(value="/user",method&nbsp;=&nbsp;RequestMethod.GET)&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;public&nbsp;@ResponseBody&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;User&nbsp;printUser(@RequestParam(value&nbsp;=&nbsp;"id",&nbsp;required&nbsp;=&nbsp;false,&nbsp;defaultValue&nbsp;=&nbsp;"0")&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;int&nbsp;id)&nbsp;{&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;user&nbsp;=&nbsp;new&nbsp;User();&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user&nbsp;=&nbsp;userService.getUserById(id);&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;user;&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;@RequestMapping(value="/user/{id}",method&nbsp;=&nbsp;RequestMethod.GET)&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;public&nbsp;@ResponseBody&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;User&nbsp;printUser2(@PathVariable&nbsp;int&nbsp;id)&nbsp;{&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;User&nbsp;user&nbsp;=&nbsp;new&nbsp;User();&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user&nbsp;=&nbsp;userService.getUserById(id);&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;user;&nbsp;&nbsp;</li><li style="list-style-type: decimal; line-height: 1.6;">&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li></ol></div><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><br style="margin: 0px; padding: 0px;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">上面两个方法，访问路径分别如下：</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;">&nbsp;</p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><img src="http://img.blog.csdn.net/20150407183110261?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3VnZTkwNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" style="margin: 0px; padding: 0px; border: 0px; max-width: 660px;" /><br style="margin: 0px; padding: 0px;" /></p><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff;"><img src="http://img.blog.csdn.net/20150407183012061?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3VnZTkwNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" style="margin: 0px; padding: 0px; border: 0px; max-width: 660px;" /></p><img src ="http://www.blogjava.net/jlin/aggbug/433344.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2018-08-22 11:05 <a href="http://www.blogjava.net/jlin/archive/2018/08/22/433344.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SVN命令学习</title><link>http://www.blogjava.net/jlin/archive/2018/05/25/433235.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Fri, 25 May 2018 05:46:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2018/05/25/433235.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433235.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2018/05/25/433235.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433235.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433235.html</trackback:ping><description><![CDATA[<div>svn　add　文件名/目录</div><div>svn　ci　　文件名/目录 -m　&#8220;提交备注信息文本&#8220;</div><div>svn检查本地文件是否有改动，并显示文件名：</div><div>svn diff --diff-cmd "diff" -x "-q" . | grep Index | cut -d " " -f 2</div><div>检查本地目录改动及提交SVN:</div><div>svn diff --diff-cmd "diff" -x "-q" . | grep Index | cut -d " " -f 2 | svn ci -m "test"</div><div>提交同一个目录下的多个文件： svn ci -m "" 目录</div><div>提交多个文件，使用空格来间隔这多个文件： svn ci &nbsp;file1 file2 &#8230; filen -m &#8220;&#8221;</div><div>同一目录下的未加入版本库添加: svn add *&nbsp;</div><div>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</div><div>查看一个文件每一行最后更改的详情（版本、作业）</div><div>svn blame filename</div><div>查看一个文件所有更改历史详情</div><div>svn log --diff filename</div><img src ="http://www.blogjava.net/jlin/aggbug/433235.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2018-05-25 13:46 <a href="http://www.blogjava.net/jlin/archive/2018/05/25/433235.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用java8的lambda将list转为map（转）</title><link>http://www.blogjava.net/jlin/archive/2018/03/31/433138.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Sat, 31 Mar 2018 12:22:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2018/03/31/433138.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433138.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2018/03/31/433138.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433138.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433138.html</trackback:ping><description><![CDATA[<div style="margin: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px; background-color: #fefef2;"><h3>常用方式</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">代码如下：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;Long, String&gt; getIdNameMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getId, Account::getUsername)); } </code></pre><h3>收集成实体本身map</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">代码如下：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;Long, Account&gt; getIdAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getId, account -&gt; account)); } </code></pre><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">account -&gt; account</strong>是一个返回本身的lambda表达式，其实还可以使用Function接口中的一个默认方法代替，使整个方法更简洁优雅：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;Long, Account&gt; getIdAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getId, Function.identity())); } </code></pre><h3>重复key的情况</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">代码如下：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;String, Account&gt; getNameAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity())); } </code></pre><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">这个方法可能报错（<strong style="margin: 0px; padding: 0px;">java.lang.IllegalStateException: Duplicate key</strong>），因为name是有可能重复的。<strong style="margin: 0px; padding: 0px;">toMap</strong>有个重载方法，可以传入一个合并的函数来解决key冲突问题：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;String, Account&gt; getNameAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity(), (key1, key2) -&gt; key2)); } </code></pre><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">这里只是简单的使用后者覆盖前者来解决key重复问题。</p><h3>指定具体收集的map</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">toMap</strong>还有另一个重载方法，可以指定一个Map的具体实现，来收集数据：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;String, Account&gt; getNameAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity(), (key1, key2) -&gt; key2, LinkedHashMap::new)); } </code></pre></div><div style="margin: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px; background-color: #fefef2;">&nbsp;</div><div style="margin: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px; background-color: #fefef2;"><div style="margin: 0px;">转自：https://zacard.net/2016/03/17/java8-list-to-map/</div></div><img src ="http://www.blogjava.net/jlin/aggbug/433138.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2018-03-31 20:22 <a href="http://www.blogjava.net/jlin/archive/2018/03/31/433138.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用java8的lambda将list转为map（转）</title><link>http://www.blogjava.net/jlin/archive/2018/03/31/433137.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Sat, 31 Mar 2018 12:21:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2018/03/31/433137.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433137.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2018/03/31/433137.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433137.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433137.html</trackback:ping><description><![CDATA[<div style="margin: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px; background-color: #fefef2;"><h3>常用方式</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">代码如下：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;Long, String&gt; getIdNameMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getId, Account::getUsername)); } </code></pre><h3>收集成实体本身map</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">代码如下：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;Long, Account&gt; getIdAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getId, account -&gt; account)); } </code></pre><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">account -&gt; account</strong>是一个返回本身的lambda表达式，其实还可以使用Function接口中的一个默认方法代替，使整个方法更简洁优雅：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;Long, Account&gt; getIdAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getId, Function.identity())); } </code></pre><h3>重复key的情况</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">代码如下：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;String, Account&gt; getNameAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity())); } </code></pre><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">这个方法可能报错（<strong style="margin: 0px; padding: 0px;">java.lang.IllegalStateException: Duplicate key</strong>），因为name是有可能重复的。<strong style="margin: 0px; padding: 0px;">toMap</strong>有个重载方法，可以传入一个合并的函数来解决key冲突问题：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;String, Account&gt; getNameAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity(), (key1, key2) -&gt; key2)); } </code></pre><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;">这里只是简单的使用后者覆盖前者来解决key重复问题。</p><h3>指定具体收集的map</h3><p style="margin-top: 10px; margin-bottom: 10px; padding: 0px; line-height: 1.5;"><strong style="margin: 0px; padding: 0px;">toMap</strong>还有另一个重载方法，可以指定一个Map的具体实现，来收集数据：</p><pre style="margin-top: 0px; margin-bottom: 0px; padding: 0px; white-space: pre-wrap; word-wrap: break-word;"><code style="margin: 0px; padding: 0px;">public Map&lt;String, Account&gt; getNameAccountMap(List&lt;Account&gt; accounts) {     return accounts.stream().collect(Collectors.toMap(Account::getUsername, Function.identity(), (key1, key2) -&gt; key2, LinkedHashMap::new)); } </code></pre></div><div style="margin: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px; background-color: #fefef2;">&nbsp;</div><div style="margin: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 19.5px; background-color: #fefef2;"><div style="margin: 0px;">转自：https://zacard.net/2016/03/17/java8-list-to-map/</div></div><img src ="http://www.blogjava.net/jlin/aggbug/433137.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2018-03-31 20:21 <a href="http://www.blogjava.net/jlin/archive/2018/03/31/433137.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring3中js/css/jpg/gif等静态资源无法找到（No mapping found for HTTP request with URI）问题</title><link>http://www.blogjava.net/jlin/archive/2018/01/30/433031.html</link><dc:creator>fly</dc:creator><author>fly</author><pubDate>Tue, 30 Jan 2018 08:16:00 GMT</pubDate><guid>http://www.blogjava.net/jlin/archive/2018/01/30/433031.html</guid><wfw:comment>http://www.blogjava.net/jlin/comments/433031.html</wfw:comment><comments>http://www.blogjava.net/jlin/archive/2018/01/30/433031.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jlin/comments/commentRss/433031.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jlin/services/trackbacks/433031.html</trackback:ping><description><![CDATA[<p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;">我们在使用spring3的时候，如果使用了注解的话，我们会发现，有时候我们界面的js/css/jpg/gif等文件会出现找不到的情况，然而检查引用路径，发现无论是绝对路径还是相对路径，都没错。这下我们就纠结了，到底是什么问题呢？</span></p><p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;">楼主我也是苦思良久，不经意间看到了后台的日志，才发现是spring搞的鬼。</span></p><p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;"><br style="box-sizing: border-box;" /></span></p><p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;">报错信息：<span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #ff0000;">&lt;No mapping found for HTTP request with URI [/sandDemo001/images/1.jpg] in DispatcherServlet with name 'spring'&gt;</span></span></p><p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #ff0000;"><br style="box-sizing: border-box;" /></span></span></p><p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;"><span style="box-sizing: border-box; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #330033;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #ff0000; font-size: 18px;"><strong style="box-sizing: border-box;">解决方法1</strong></span>：<span style="box-sizing: border-box; margin: 0px; padding: 0px; font-size: 14px;"><strong style="box-sizing: border-box;">在spring的配置修改</strong></span></span><span style="box-sizing: border-box; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #330033;">web.xml<span style="box-sizing: border-box; margin: 0px; padding: 0px; font-size: 14px;"><strong style="box-sizing: border-box;">下对</strong></span>spring<span style="box-sizing: border-box; margin: 0px; padding: 0px; font-size: 14px;"><strong style="box-sizing: border-box;">的</strong></span>DispatcherServlet<span style="box-sizing: border-box; margin: 0px; padding: 0px; font-size: 14px;"><strong style="box-sizing: border-box;">请求</strong></span>url<span style="box-sizing: border-box; margin: 0px; padding: 0px; font-size: 14px;"><strong style="box-sizing: border-box;">映射的配置，先来看看原配置</strong></span>：</span><br style="box-sizing: border-box;" /></span></span></span></p><div bg_html"="" style="box-sizing: border-box; position: relative; overflow-y: hidden; width: 851.391px; color: #454545;"><div style="box-sizing: border-box; margin: 0px;"><div style="box-sizing: border-box; margin: 0px; border-right: 1px solid #e7e5dc;"><strong style="box-sizing: border-box;">[html]</strong>&nbsp;<a href="http://blog.csdn.net/miss_kun/article/details/52047381#" title="view plain" style="box-sizing: border-box; background-image: url(&quot;../images/ico_plain.gif&quot;); background-position: left top; background-repeat: no-repeat; padding: 1px; outline: 0px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px;">view plain</a><span data-mod="popu_168" style="box-sizing: border-box; margin: 0px; padding: 0px;">&nbsp;<a href="http://blog.csdn.net/miss_kun/article/details/52047381#" title="copy" style="box-sizing: border-box; background-image: url(&quot;../images/ico_copy.gif&quot;); background-position: left top; background-repeat: no-repeat; padding: 1px; outline: 0px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px;">copy</a><div style="box-sizing: border-box; margin: 0px; position: absolute; left: 259px; top: 453px; width: 16px; height: 16px; z-index: 99;"></div></span></div></div><ol start="1" style="box-sizing: border-box; border-right: 1px solid #e7e5dc;"><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">spring</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-class</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">org.springframework.web.servlet.DispatcherServlet</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-class</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">load-on-startup</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">1</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">load-on-startup</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">spring</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li></ol></div><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #330033;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;">&lt;servlet-mapping&gt;</span><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;">的</span><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;">&lt;url-pattern&gt;/&lt;/url-pattern&gt;</span></span><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #330033;">把所有的请求都交给spring去处理了，而所有available的请求url都是在Constroller里使用类似@RequestMapping(value = "/login/{user}", method = RequestMethod.GET)这样的注解配置的，这样的话对js/css/jpg/gif等静态资源的访问就会得不到。所以，在<span style="box-sizing: border-box; margin: 0px; padding: 0px;">web.xml里添加如下的配置就可以解决该问题了。</span></span></span></span><p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"></p><p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial;"><span style="box-sizing: border-box; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; margin: 0px; padding: 0px;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #330033;"></span></span></span></span></span></span></p><div bg_html"="" style="box-sizing: border-box; position: relative; overflow-y: hidden; width: 851.391px; color: #454545;"><div style="box-sizing: border-box; margin: 0px;"><div style="box-sizing: border-box; margin: 0px; border-right: 1px solid #e7e5dc;"><strong style="box-sizing: border-box;">[html]</strong>&nbsp;<a href="http://blog.csdn.net/miss_kun/article/details/52047381#" title="view plain" style="box-sizing: border-box; background-image: url(&quot;../images/ico_plain.gif&quot;); background-position: left top; background-repeat: no-repeat; padding: 1px; outline: 0px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px;">view plain</a><span data-mod="popu_168" style="box-sizing: border-box; margin: 0px; padding: 0px;">&nbsp;<a href="http://blog.csdn.net/miss_kun/article/details/52047381#" title="copy" style="box-sizing: border-box; background-image: url(&quot;../images/ico_copy.gif&quot;); background-position: left top; background-repeat: no-repeat; padding: 1px; outline: 0px; display: inline-block; width: 16px; height: 16px; text-indent: -2000px;">copy</a><div style="box-sizing: border-box; margin: 0px; position: absolute; left: 259px; top: 754px; width: 16px; height: 16px; z-index: 99;"></div></span></div></div><ol start="1" style="box-sizing: border-box; border-right: 1px solid #e7e5dc;"><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">default</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">*.css</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;</span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;"><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">default</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">*.gif</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">default</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">*.jpg</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">default</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-name</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">*.js</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">url-pattern</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li><li style="box-sizing: border-box; line-height: 18px;"><span style="box-sizing: border-box;">&nbsp;<span style="box-sizing: border-box; font-weight: 700; color: #993300;">&lt;/</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">servlet-mapping</span><span style="box-sizing: border-box; font-weight: 700; color: #993300;">&gt;</span><span style="box-sizing: border-box;">&nbsp;&nbsp;</span></span></li></ol></div><p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"></p><p style="box-sizing: border-box; margin: 10px 0px; padding: 0px; color: #454545; background-color: #ffffff; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px;"><strong style="box-sizing: border-box;"><strong style="box-sizing: border-box;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-weight: 400; font-family: Arial; color: #ff0000; font-size: 18px;">解决方法2：<span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #000000; font-size: 14px;">在spring的配置文件中添加如下一行：</span></span></strong></strong></p><p style="box-sizing: border-box; margin: 10px 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><strong style="box-sizing: border-box;"></strong><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #660000; font-size: 14px;"><strong style="box-sizing: border-box;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-weight: 400; color: #006699;">&lt;mvc:default-servlet-handler/&gt;</span></strong></span></p><p style="box-sizing: border-box; margin: 10px 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #660000; font-size: 14px;">注意，需要是spring3.0.5以上版本</span></p><br style="box-sizing: border-box; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;" /><span style="box-sizing: border-box; margin: 0px; padding: 0px; background-color: #ffffff; color: #ff0000; font-family: Arial; font-size: 18px;"><strong style="box-sizing: border-box;">解决方法3：</strong></span><span style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; background-color: #ffffff; font-family: Arial;"><strong style="box-sizing: border-box;">在spring的配置文件中添加如下一行：</strong></span><br style="box-sizing: border-box; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;" /><p style="box-sizing: border-box; margin: 0px; padding: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff;"><span style="box-sizing: border-box; margin: 0px; padding: 0px; font-family: Arial; color: #330033;"></span></p><div style="box-sizing: border-box; margin: 0px; color: #454545; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, SimHei, Arial, SimSun; font-size: 16px; background-color: #ffffff; overflow: hidden;">&lt;!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory --&gt;<br style="box-sizing: border-box;" />&nbsp;<br style="box-sizing: border-box;" />&nbsp;&lt;mvc:resources mapping="/resources/**" location="/resources/" /&gt;&nbsp;<br style="box-sizing: border-box;" />&nbsp;&nbsp;<br style="box-sizing: border-box;" />这个配置告诉spring 静态资源的处理方式<br /><br />转：&nbsp;<span style="font-family: verdana, &quot;courier new&quot;; font-size: 14px;">http://blog.csdn.net/miss_kun/article/details/52047381</span></div><div></div><img src ="http://www.blogjava.net/jlin/aggbug/433031.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jlin/" target="_blank">fly</a> 2018-01-30 16:16 <a href="http://www.blogjava.net/jlin/archive/2018/01/30/433031.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>