diff --git a/contents/android-sdk-installation-doesnt-find-jdk.md b/contents/android-sdk-installation-doesnt-find-jdk.md index 117b823..3b51ee0 100644 --- a/contents/android-sdk-installation-doesnt-find-jdk.md +++ b/contents/android-sdk-installation-doesnt-find-jdk.md @@ -1,15 +1,15 @@ -##安装Android SDK的时候找不到JDK +## 安装Android SDK的时候找不到JDK -###问题 +### 问题 我在我的win7 64位的系统上安装Android SDK时,jdk-6u23-windows-x64.exe已经安装上了,但是Android SDK的安装程序却因为找不到已安装的JDK无法继续下去。 这个问题出现过吗?有没有办法解决呢?  -###回答1: +### 回答1: 当你看到这个提示(找不到jdk)的时候按Back(返回),然后再点Next(下一步)。这个时候,它将会去寻找JDK -###回答2: +### 回答2: 实际安装: - 系统:windows 8.1 diff --git a/contents/avoiding-null-statements-in-java.md b/contents/avoiding-null-statements-in-java.md index c2a1348..b963879 100644 --- a/contents/avoiding-null-statements-in-java.md +++ b/contents/avoiding-null-statements-in-java.md @@ -1,6 +1,6 @@ -##去掉烦人的“!=null"(判空语句) +## 去掉烦人的“!=null"(判空语句) -###问题 +### 问题 为了避免空指针调用,我们经常会看到这样的语句 ```java if (someobject != null) { @@ -9,7 +9,7 @@ if (someobject != null) { ``` 最终,项目中会存在大量判空代码,多么丑陋繁冗!如何避免这种情况?我们是否滥用了判空呢? -###回答 +### 回答 这是初、中级程序猿经常会遇到的问题。他们总喜欢在方法中返回null,因此,在调用这些方法时,也不得不去判空。另外,也许受此习惯影响,他们总潜意识地认为,所有的返回都是不可信任的,为了保护自己程序,就加了大量的判空。 @@ -20,7 +20,7 @@ if (someobject != null) { 你可能还不明白这两句话的意思,不急,继续往下看,接下来将详细讨论这两种情况 -####先说第2种情况 +#### 先说第2种情况 null就是一个不合理的参数,就应该明确地中断程序,往外抛错误。这种情况常见于api方法。例如你开发了一个接口,id是一个必选的参数,如果调用方没传这个参数给你,当然不行。你要感知到这个情况,告诉调用方“嘿,哥们,你传个null给我做甚"。 相对于判空语句,更好的检查方式有两个 @@ -28,7 +28,7 @@ null就是一个不合理的参数,就应该明确地中断程序,往外抛 1. assert语句,你可以把错误原因放到assert的参数中,这样不仅能保护你的程序不往下走,而且还能把错误原因返回给调用方,岂不是一举两得。(原文介绍了assert的使用,这里省略) 2. 也可以直接抛出空指针异常。上面说了,此时null是个不合理的参数,有问题就是有问题,就应该大大方方往外抛。 -####第1种情况会更复杂一些。 +#### 第1种情况会更复杂一些。 这种情况下,null是个”看上去“合理的值,例如,我查询数据库,某个查询条件下,就是没有对应值,此时null算是表达了“空”的概念。 这里给一些实践建议: @@ -88,7 +88,7 @@ ParserFactory.getParser().findAction(someInput).doSomething(); -####其他回答精选: +#### 其他回答精选: - 如果要用equal方法,请用object<不可能为空>.equal(object<可能为空>)) 例如: 使用 diff --git a/contents/breaking-out-of-nested-loops-in-java.md b/contents/breaking-out-of-nested-loops-in-java.md index d145828..fca3bce 100644 --- a/contents/breaking-out-of-nested-loops-in-java.md +++ b/contents/breaking-out-of-nested-loops-in-java.md @@ -1,6 +1,6 @@ -##从一个多层嵌套循环中直接跳出 +## 从一个多层嵌套循环中直接跳出 -###问题 +### 问题 Java中如何从一个多层嵌套循环中退出,例如下面,有两个循环,break只能退出一个for循环,不能直接跳过第二个for循环 ```java for (Type type : types) { @@ -12,7 +12,7 @@ for (Type type : types) { }} ``` -###回答 +### 回答 可以用break+label的语法,例子如下 ```java diff --git a/contents/check-if-at-least-two-out-of-three-booleans-are-true.md b/contents/check-if-at-least-two-out-of-three-booleans-are-true.md index f2f6eb0..cb62ef6 100644 --- a/contents/check-if-at-least-two-out-of-three-booleans-are-true.md +++ b/contents/check-if-at-least-two-out-of-three-booleans-are-true.md @@ -1,6 +1,6 @@ -##给3个布尔变量,当其中有2个或者2个以上为true才返回true +## 给3个布尔变量,当其中有2个或者2个以上为true才返回true -###问题 +### 问题 给3个boolean变量,a,b,c,当其中有2个或2个以上为true时才返回true? * 最笨的方法: ```java diff --git a/contents/convert-a-string-to-an-enum-in-java.md b/contents/convert-a-string-to-an-enum-in-java.md index d9474b9..947c336 100644 --- a/contents/convert-a-string-to-an-enum-in-java.md +++ b/contents/convert-a-string-to-an-enum-in-java.md @@ -1,4 +1,4 @@ -##如何将String转换为enum +## 如何将String转换为enum ### 问题 假设定义了如下的enum(枚举): diff --git a/contents/converting-string-to-int-in-java.md b/contents/converting-string-to-int-in-java.md index 7cdd029..6b634e4 100644 --- a/contents/converting-string-to-int-in-java.md +++ b/contents/converting-string-to-int-in-java.md @@ -1,4 +1,4 @@ -##如何将String转换为Int +## 如何将String转换为Int 有两种方式 diff --git a/contents/create-arraylist-from-array.md b/contents/create-arraylist-from-array.md index 7d58c8f..9da081b 100644 --- a/contents/create-arraylist-from-array.md +++ b/contents/create-arraylist-from-array.md @@ -1,17 +1,17 @@ -##将数组转换为List +## 将数组转换为List -###问题 +### 问题 假设有数组 ```java Element[] array = {new Element(1),new Element(2),new Element(3)}; ``` 如何将其转换为ArrayList`<Element>` arraylist = ??? -### 回答1 ### +### 回答1 `new ArrayList<Element>(Arrays.asList(array))` -###回答2 +### 回答2 Arrays.asList(array)或者Arrays.asList(new Element(1),new Element(2),new Element(3)) diff --git a/contents/dealing-with-java-lang-outofmemoryerror-permgen-space-error.md b/contents/dealing-with-java-lang-outofmemoryerror-permgen-space-error.md index ffa7f7a..dd9aa13 100644 --- a/contents/dealing-with-java-lang-outofmemoryerror-permgen-space-error.md +++ b/contents/dealing-with-java-lang-outofmemoryerror-permgen-space-error.md @@ -1,6 +1,6 @@ -##如何处理 java.lang.outOfMemoryError PermGen space error +## 如何处理 java.lang.outOfMemoryError PermGen space error -###问题 +### 问题 最近,我在过运行我的web应用时得到:java.lang.OutOfMemoryError: PermGen space。 我的应用是一个典型的 Hibernate/JPA + IceFaces/JSF的应用.运行于Tomcat6.0和jdk1.6.我发布了多次以后,产生了这个错误。 @@ -8,7 +8,7 @@ 是什么原因造成的,我如何避免?我怎样修复? -#回答 +### 回答 解决的方案是当TomeCat启时,在jvm的的命令行添加参数 diff --git a/contents/declare-array-in-java.md b/contents/declare-array-in-java.md index 1247686..238fc9e 100644 --- a/contents/declare-array-in-java.md +++ b/contents/declare-array-in-java.md @@ -1,9 +1,9 @@ -##在java中声明数组 +## 在java中声明数组 -###问题描述: +### 问题描述: 你是如何在Java中声明数组的。 -###回答: +### 回答: 你可以直接用数组声明,或者通过数组的字面常量(array literal )声明 对于原始类型(primitive types): diff --git a/contents/does-finally-always-execute-in-java.md b/contents/does-finally-always-execute-in-java.md index 96e7234..b532824 100644 --- a/contents/does-finally-always-execute-in-java.md +++ b/contents/does-finally-always-execute-in-java.md @@ -1,4 +1,4 @@ -##问题 +## 问题 有一个 try/catch 代码块,其中包含一个打印语句。finally代码块总会被执行么? @@ -17,7 +17,7 @@ finally { } ``` -##回答 +## 回答 1. ```finally``` 将会被调用。 只有以下情况 ```finally``` 不会被调用: diff --git a/contents/get-current-stack-trace-in-java.md b/contents/get-current-stack-trace-in-java.md index 9b17cc6..50c1829 100644 --- a/contents/get-current-stack-trace-in-java.md +++ b/contents/get-current-stack-trace-in-java.md @@ -1,9 +1,9 @@ -##获取完整的堆栈信息 +## 获取完整的堆栈信息 -###问题 +### 问题 捕获了异常后,如何获取完整的堆栈轨迹(stack trace) -###回答 +### 回答 ```java String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e) ``` diff --git a/contents/how-can-i-convert-a-stack-trace-to-a-string.md b/contents/how-can-i-convert-a-stack-trace-to-a-string.md index 7a15500..44e486c 100644 --- a/contents/how-can-i-convert-a-stack-trace-to-a-string.md +++ b/contents/how-can-i-convert-a-stack-trace-to-a-string.md @@ -1,13 +1,13 @@ -#怎样将堆栈追踪信息转换为字符串 -##问题 +# 怎样将堆栈追踪信息转换为字符串 +## 问题 将`Throwable.getStackTrace()`的结果转换为一个字符串来来描述堆栈信息的最简单的方法是什么 -###最佳答案 +### 最佳答案 可以用下面的方法将异常堆栈信息转换为字符串类型。该类在Apache commons-lang-2.2.jar中可以找到: [`org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)`](org.apache.commons.lang.exception.ExceptionUtils.getStackTrace\(Throwable\)) -###答案二 +### 答案二 用 [`Throwable.printStackTrace(PrintWriter pw)`](https://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#printStackTrace-java.io.PrintWriter-)可以输出堆栈信息: ````java StringWriter sw = new StringWriter(); @@ -16,14 +16,14 @@ t.printStackTrace(pw); sw.toString(); // stack trace as a string ```` -###答案三 +### 答案三 ````java StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); String exceptionAsString = sw.toString(); ```` -###答案四 +### 答案四 ````java public String stackTraceToString(Throwable e) { StringBuilder sb = new StringBuilder(); diff --git a/contents/how-can-i-generate-an-md5-hash.md b/contents/how-can-i-generate-an-md5-hash.md index b122024..e48e5c7 100644 --- a/contents/how-can-i-generate-an-md5-hash.md +++ b/contents/how-can-i-generate-an-md5-hash.md @@ -1,10 +1,10 @@ -##如何计算MD5值 +## 如何计算MD5值 -###问题 +### 问题 Java中有没有方法可以计算一个String的MD5值? -###回答 +### 回答 你可以用 ```MessageDigest``` 的MD5实例来计算String的MD5值。 使用 ```MessageDigest``` 和 String 时,一定要显式声明你的数据编码类型。如果你使用无参的 ```String.getBytes()``` , 它会以当前平台的默认编码来转换数据。不同平台的默认编码可能是不同的,这可能会导致你的数据不一致。 diff --git a/contents/how-do-i-call-one-constructor-from-another-in-java.md b/contents/how-do-i-call-one-constructor-from-another-in-java.md index a7d62cd..3e16197 100644 --- a/contents/how-do-i-call-one-constructor-from-another-in-java.md +++ b/contents/how-do-i-call-one-constructor-from-another-in-java.md @@ -1,11 +1,11 @@ -##能否在一个构造器中调用另一个构造器 +## 能否在一个构造器中调用另一个构造器 -###问题 +### 问题 能否在一个构造器中调用另一个构造器(在同一个类中,不是子类)?如果可以,怎么做? 调用另一个构造器的最好方法是什么(如果有几种方法可以选择的话)? -###回答 +### 回答 可以这样做: ```java public class Foo diff --git a/contents/how-do-i-compare-strings-in-java.md b/contents/how-do-i-compare-strings-in-java.md index 54d17e1..4972cc0 100644 --- a/contents/how-do-i-compare-strings-in-java.md +++ b/contents/how-do-i-compare-strings-in-java.md @@ -1,4 +1,4 @@ -##在java中如何对比(compare)string +## 在java中如何对比(compare)string - `==`对应的是指针相等,也就是他们是否为同一个对象 - `.equals()`对应的是值相等,也就是逻辑相等 @@ -39,6 +39,6 @@ new String("test") == new String("test") // --> false } ``` -###其他 +### 其他 - 如果你重写了equal方法,记得相对应地修改hashcode方法,否则将会违反这两个方法的对等关系,如果两个对象是相等(equal)的,那么两个对象调用hashCode必须产生相同的整数结果,即:equal为true,hashCode必须为true,equal为false,hashCode也必须为false - 如果要忽略大小写进行对比,可以用equalsIgnoreCase()方法 diff --git a/contents/how-do-i-create-a-java-string-from-the-contents-of-a-file.md b/contents/how-do-i-create-a-java-string-from-the-contents-of-a-file.md index 1dc835b..ec9bca2 100644 --- a/contents/how-do-i-create-a-java-string-from-the-contents-of-a-file.md +++ b/contents/how-do-i-create-a-java-string-from-the-contents-of-a-file.md @@ -1,6 +1,6 @@ -##如何从文件里读取字符串 +## 如何从文件里读取字符串 -###从文件里读取所有文本: +### 从文件里读取所有文本: 代码: ```java @@ -13,14 +13,14 @@ static String readFile(String path, Charset encoding) ``` -###一行一行读入文本: +### 一行一行读入文本: Java 7 提供了一个方便的方法可以直接将文件中的文本一行一行读入,存放在一个List容器里。 ```JAVA List<String> lines = Files.readAllLines(Paths.get(path), encoding); ``` -###内存使用率 +### 内存使用率 第一个方法,一次读取所有文本的方法,占用内存较多,因为它一次性保留了文件的所有原始信息,包括换行符之类的“无用”字符。 @@ -30,7 +30,7 @@ List<String> lines = Files.readAllLines(Paths.get(path), encoding); 这里的“很大”是相对于计算机性能的。一般来说,几十个G的文件应当算是大文件。 -###字符编码 +### 字符编码 还有一件事需要注意,就是字符编码。不同的平台有自己的默认编码,所以有时候你的程序需要指定编码,来保持平台无关/跨平台。 diff --git a/contents/how-do-servlets-work-instantiation-shared-variables-and-multithreading.md b/contents/how-do-servlets-work-instantiation-shared-variables-and-multithreading.md index 4539697..6f5ef34 100644 --- a/contents/how-do-servlets-work-instantiation-shared-variables-and-multithreading.md +++ b/contents/how-do-servlets-work-instantiation-shared-variables-and-multithreading.md @@ -14,7 +14,7 @@ servletcontainer 是附属于webserver的,而这个webserver会持续监听一 在有filter的情况下,```doFilter()```方法会被触发。当代码调用```chain.doFilter(request, response)```时候,请求会经过下一个过滤器filter,如果没有了过滤器,会到达servlet。在servlets的情况下,```service()```触发,然后根据```request.getMethod()```确定执行doGet()还是```doPost()```,如果当前servlet找不到请求的方法,返回405error。 request对象提供了HTTP请求所有的信息,比如request headers和request body,response对象提供了控制和发送HTTP响应的的能力,并且以你想要的方式,比如设置headers和body。当HTTP响应结束,请求和响应对象会被销毁(实际上,大多数container将会清洗到这些对象的状态然后回收这些事例以重新利用) -####httpSession +#### httpSession 当客户端第一次访问webapp或者通过```request.getSession()```方法第一次获取httpSession ,servletcontainer 将会创建一个新的HttpSession 对象,产生一个长的唯一的ID标记session(可以通过session.getId()),并且将这个session存储在server内存中。servletcontainer 同时会在HTTP response的Header中设置```Set-Cookie```cookie值,其中cookie name为JSESSIONID,cookie value为唯一的长ID值。 diff --git a/contents/how-to-avoid-java-code-in-jsp-files.md b/contents/how-to-avoid-java-code-in-jsp-files.md index d0fc7e5..9618d47 100644 --- a/contents/how-to-avoid-java-code-in-jsp-files.md +++ b/contents/how-to-avoid-java-code-in-jsp-files.md @@ -1,6 +1,6 @@ -##如何避免在JSP文件中使用Java代码 +## 如何避免在JSP文件中使用Java代码 -###问题 +### 问题 如何避免在JSP文件中使用Java代码? 我对Java EE不是很熟悉,我知道类似如下的三行代码 @@ -11,7 +11,7 @@ ``` 这三行代码是学校教的老式代码。在JSP 2,存在一些方法可以避免在JSP文件中使用Java代码。有人可以告诉我在JSP 2中如何避免使用Java代码吗,这些方法该如何使用? -###回答 +### 回答 在大约十年前,taglibs(比如JSTL)和EL(EL表达式,`${}`)诞生的时候,在JSP中使用scriptlets(类似`<% %>`)这种做法,就确实已经是不被鼓励使用的做法了。 scriptlets 主要的缺点有: diff --git a/contents/how-to-concatenate-two-arrays-in-java.md b/contents/how-to-concatenate-two-arrays-in-java.md index cecdd67..d3cff4f 100644 --- a/contents/how-to-concatenate-two-arrays-in-java.md +++ b/contents/how-to-concatenate-two-arrays-in-java.md @@ -1,6 +1,6 @@ -##如何便捷地将两个数组合到一起 +## 如何便捷地将两个数组合到一起 -###一行代码搞定 +### 一行代码搞定 Apache Commons Lang library [`ArrayUtils.addAll(T[], T...)`](http://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/ArrayUtils.html#addAll%28T%5B%5D,%20T...%29)就是专门干这事的 代码: @@ -8,9 +8,9 @@ Apache Commons Lang library [`ArrayUtils.addAll(T[], T...)`](http://commons.apac String[] both = ArrayUtils.addAll(first, second); ``` -###不借助依赖包 +### 不借助依赖包 -####非泛型 +#### 非泛型 把下面的`Foo`替换成你自己的类名 ```java public Foo[] concat(Foo[] a, Foo[] b) { @@ -23,7 +23,7 @@ public Foo[] concat(Foo[] a, Foo[] b) { } ``` -####泛型 +#### 泛型 ```java public <T> T[] concatenate (T[] a, T[] b) { int aLen = a.length; diff --git a/contents/how-to-split-a-string-in-java.md b/contents/how-to-split-a-string-in-java.md index f55e151..8b81769 100644 --- a/contents/how-to-split-a-string-in-java.md +++ b/contents/how-to-split-a-string-in-java.md @@ -1,4 +1,4 @@ -##如何分割(split)string字符串 +## 如何分割(split)string字符串 使用[`String#split()`](http://docs.oracle.com/javase/8/docs/api/java/lang/String.html#split-java.lang.String-)方法 如下所示: diff --git a/contents/in-java-whats-the-difference-between-public-default-protected-and-private.md b/contents/in-java-whats-the-difference-between-public-default-protected-and-private.md index 51dbc6c..576b49d 100644 --- a/contents/in-java-whats-the-difference-between-public-default-protected-and-private.md +++ b/contents/in-java-whats-the-difference-between-public-default-protected-and-private.md @@ -1,4 +1,4 @@ -##Java修饰符:public,protected,private,不加修饰符。有什么区别呢? +## Java修饰符:public,protected,private,不加修饰符。有什么区别呢? 如下表所示,Y表示能访问(可见性),N表示不能访问,例如第一行的第3个Y,表示类的变量/方法如果是用public修饰,它的子类能访问这个变量/方法 diff --git a/contents/initialization-of-an-arraylist-in-one-line.md b/contents/initialization-of-an-arraylist-in-one-line.md index 5541e13..a6b5972 100644 --- a/contents/initialization-of-an-arraylist-in-one-line.md +++ b/contents/initialization-of-an-arraylist-in-one-line.md @@ -1,6 +1,6 @@ 如何用一行代码初始化一个ArrayList -###问题 +### 问题 为了测试,我需要临时快速创建一个list。一开始我这样做: ```java ArrayList<String> places = new ArrayList<String>(); @@ -15,9 +15,9 @@ ArrayList<String> places = new ArrayList<String>( ``` 是否有更加简便的方法呢? -###回答 +### 回答 -####常见方式 +#### 常见方式 实际上,也许“最好”的方式,就是你写的这个方式,因为它不用再创建新的`List`: ``` ArrayList<String> list = new ArrayList<String>(); @@ -27,7 +27,7 @@ list.add("C"); ``` 只是这个方式看上去要多写些代码,让人郁闷 -####匿名内部类 +#### 匿名内部类 当然,还有其他方式,例如,写一个匿名内部类,然后在其中做初始化(也被称为 brace initialization): ``` ArrayList<String> list = new ArrayList<String>() {{ @@ -38,11 +38,11 @@ ArrayList<String> list = new ArrayList<String>() {{ ``` 但是,我不喜欢这个方式。只是为了做个初始化,却要在`ArrayList`的同一行后面加这么一坨代码。 -####Arrays.asList +#### Arrays.asList ``` List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata"); ``` -####Collections.singletonList +#### Collections.singletonList ``` List<String> places = Collections.singletonList("Buenos Aires"); ``` diff --git a/contents/is-there-a-unique-android-device-id.md b/contents/is-there-a-unique-android-device-id.md index 4853256..284b008 100644 --- a/contents/is-there-a-unique-android-device-id.md +++ b/contents/is-there-a-unique-android-device-id.md @@ -1,9 +1,9 @@ -##如何获取Android设备唯一ID? +## 如何获取Android设备唯一ID? -###问题 +### 问题 每一个android设备都有唯一ID吗?如果有?怎么用java最简单取得呢? -###回答1(最佳) +### 回答1(最佳) 如何取得android唯一码? @@ -63,7 +63,7 @@ return unique ID of build information (may overlap data - API < 9) // Finally, combine the values we have found by using the UUID class to create a unique identifier return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();} ``` -###回答2 +### 回答2 好处: - 1.不需要特定权限. - 2.在100% Android装置(包括root过的)上,保证唯一性. @@ -91,7 +91,7 @@ public synchronized static String id(Context context) { } ``` -###回答3(需要有电话卡) +### 回答3(需要有电话卡) 好处: 1.重装app之后仍能取得相同唯一值. diff --git a/contents/must-override-a-superclass-method-errors-after-importing-a-project-into-eclips.md b/contents/must-override-a-superclass-method-errors-after-importing-a-project-into-eclips.md index 723403f..23da739 100644 --- a/contents/must-override-a-superclass-method-errors-after-importing-a-project-into-eclips.md +++ b/contents/must-override-a-superclass-method-errors-after-importing-a-project-into-eclips.md @@ -1,5 +1,5 @@ -##问题 +## 问题 大多数情况下,当我重新导入项目到eclipse的时候,我重写的方法都不能被正确格式化,导致这样的错误: > The method must override a superclass method. @@ -26,7 +26,7 @@ list.setOnCreateContextMenuListener(new OnCreateContextMenuListener() { 要是手动的去修改被篡改的参数名,那是一个非常痛苦的过程。要是有人能解释为什么会出现这样的情况以及怎样去解决它,我感激不尽。 是不是因为我格式化的这个方法,是另一个方法里面的参数而导致的这样的问题呢? -##回答 +## 回答 Eclipse的默认执行环境是java 1.5况且你使用了类的声明接口方法(在java 1.6中能使用@Ovrride注释,但是在java 1.5中一个方法只能重写父类的方法) 打开你的项目,然后找到preference并且设置java的编译版本为1.6,同时也确保你的eclipse是使用JRE 1.6 来执行你的程序的。 diff --git a/contents/proper-use-cases-for-android-usermanager-isuseragoat.md b/contents/proper-use-cases-for-android-usermanager-isuseragoat.md index 06301bd..fba782b 100644 --- a/contents/proper-use-cases-for-android-usermanager-isuseragoat.md +++ b/contents/proper-use-cases-for-android-usermanager-isuseragoat.md @@ -1,6 +1,6 @@ -##安卓中“UserManger.isUserAGoat()”的合适案例? +## 安卓中“UserManger.isUserAGoat()”的合适案例? -###问题描述: +### 问题描述: 我正在看在安卓4.2里介绍的新API。当看到“UserManger”类时,我遇到了如下的“method”: public boolean isUserAGoat() Used to determine whether the user making this call is subject to teleportations. @@ -8,7 +8,7 @@ Used to determine whether the user making this call is subject to teleportations Returns whether the user making this call is a goat. 这个应该怎样使用和什么时候使用? -###回答: +### 回答: 根据他们的资料,在API21前,这个“method”用来返回“false” /** * Used to determine whether the user making this call is subject to diff --git a/contents/read-convert-an-inputstream-to-a-string.md b/contents/read-convert-an-inputstream-to-a-string.md index 8807e6f..2518bec 100644 --- a/contents/read-convert-an-inputstream-to-a-string.md +++ b/contents/read-convert-an-inputstream-to-a-string.md @@ -1,19 +1,26 @@ -##将InputStream转换为String +## 将 InputStream 转换为 String + +### 使用 Apache 库 -###使用Apache库 不重复造轮子。最靠谱的方法,还是用Apache commons IOUtils 这样简单几行代码就搞定了 + ```java StringWriter writer = new StringWriter(); IOUtils.copy(inputStream, writer, encoding); String theString = writer.toString(); ``` + 或者 + ```java String theString = IOUtils.toString(inputStream, encoding)//这个方法其实封装了上面的方法,减少了一个参数 ``` -###使用原生库 + +### 使用原生库 + 如果不想引入Apache库,也可以这样做 + ```java static String convertStreamToString(java.io.InputStream is) { java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A"); diff --git a/contents/setting-multiple-jars-in-java-classpath.md b/contents/setting-multiple-jars-in-java-classpath.md index e87a69b..12f1b7d 100644 --- a/contents/setting-multiple-jars-in-java-classpath.md +++ b/contents/setting-multiple-jars-in-java-classpath.md @@ -1,10 +1,10 @@ -##如何在classpath中设置多个jar包? +## 如何在classpath中设置多个jar包? -###问题 +### 问题 是否有一个方法可以在classpath选项中包含一个文件夹(目录)下的所有jar包? 我尝试运行`java -classpath lib/*.jar:. my.package.Program`,但是无法找到相应的类文件,可是这些类文件确实存在于命令中的jar包中。我是否需要在classpath中分别指定所有的jar包? -###回答 +### 回答 在使用Java6或者以上版本时,classpath选项可以支持通配符(wildcards)。使用方法如下: * 使用直接引用(`"`) * 使用 `*` 而不是 `*.jar` diff --git a/contents/sort-arraylist-of-custom-objects-by-property.md b/contents/sort-arraylist-of-custom-objects-by-property.md index 5c279a4..000e7ca 100644 --- a/contents/sort-arraylist-of-custom-objects-by-property.md +++ b/contents/sort-arraylist-of-custom-objects-by-property.md @@ -1,8 +1,8 @@ -##通过对象属性对常规对象的ArrayList进行排序 +## 通过对象属性对常规对象的ArrayList进行排序 -###问题 +### 问题 我读过使用Comparator对常规类的ArrayList进行排序的示例,但是它们大多数使用comparedTo(),据我了解这是一个对字符串进行操作的方法。 我想要对一个由常规对象构成的ArrayList,通过它的属性(一个Date对象,getStartDate())对ArrayList进行排序。通常情况下我这样比较它们: ```java @@ -23,7 +23,7 @@ public class RandomName { } ``` -###回答 +### 回答 以前Date声明了Comparable,它有一个像处理字符串操作那样的compareTo方法。因此你可以这样: ```java public class CustomComparator implements Comparator<MyObject> { diff --git a/contents/stringbuilder-and-stringbuffer.md b/contents/stringbuilder-and-stringbuffer.md index ace7cc5..28eb2cf 100644 --- a/contents/stringbuilder-and-stringbuffer.md +++ b/contents/stringbuilder-and-stringbuffer.md @@ -1,6 +1,6 @@ -##StringBuilder和StringBuffer有哪些区别呢 +## StringBuilder和StringBuffer有哪些区别呢 -###最主要的区别,StringBuffer的实现用了synchronized(锁),而StringBuilder没有。 +### 最主要的区别,StringBuffer的实现用了synchronized(锁),而StringBuilder没有。 因此,StringBuilder会比StringBuffer快。 diff --git a/contents/using-java-net-urlconnection-to-fire-and-handle-http-requests.md b/contents/using-java-net-urlconnection-to-fire-and-handle-http-requests.md index fd9d462..40e05de 100644 --- a/contents/using-java-net-urlconnection-to-fire-and-handle-http-requests.md +++ b/contents/using-java-net-urlconnection-to-fire-and-handle-http-requests.md @@ -1,8 +1,8 @@ -##如何使用java.net.URLConnection接收及发送HTTP请求 +## 如何使用java.net.URLConnection接收及发送HTTP请求 首先声明,下面的代码,都是基本的例子。更严谨的话,还应加入处理各种异常的代码(如IOExceptions、NullPointerException、ArrayIndexOutOfBoundsException) -###准备 +### 准备 首先,需要设置请求的URL以及charset(编码);额外的参数,则取决于各自url的要求。 ```java String url = "http://example.com"; @@ -18,7 +18,7 @@ url中附带的请求参数,必须是name=value这样的格式,每个参数 上面例子还用到了String#format()。字符拼接方式,看个人喜好,我更喜欢用这个方式。 -###发送一个[HTTP GET](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3)请求(可选:带上参数) +### 发送一个[HTTP GET](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.3)请求(可选:带上参数) 这依然是个繁琐的事情。默认的方式如下: ```java URLConnection connection = new URL(url + "?" + query).openConnection(); @@ -28,7 +28,7 @@ InputStream response = connection.getInputStream(); url和参数之间,要用?号连接。请求头(header)中的[Accept-Charset](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.2),用于告诉服务器,你所发送参数的编码。如果你不带送任何参数,也可以不管Accept-Charset。另外如果你无需设置header,也可以用[URL#openStream()](http://docs.oracle.com/javase/6/docs/api/java/net/URL.html#openStream%28%29) 而非openConnection。 不管那种方式,假设服务器端是 [HttpServlet](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServlet.html),那么你的get请求将会触发它的doGet()方法,它能通过[HttpServletRequest#getParameter()](http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getParameter%28java.lang.String%29)获取你传递的参数。 -###发送一个[HTTP POST](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5)请求,并带上参数 +### 发送一个[HTTP POST](http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5)请求,并带上参数 设置[URLConnection#setDoOutput()](http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html#setDoOutput%28boolean%29),等于隐式地将请求方法设为POST。标准的HTTP POST 表单,其Content-Tyep为application/x-www-form-urlencoded,请求的内容放到到body中。也就是如下代码: ```java URLConnection connection = new URL(url).openConnection(); @@ -56,7 +56,7 @@ httpConnection.setRequestMethod("POST"); 同样的,如果服务端是[HttpServlet](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServlet.html),将会触发它的[doPost()](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServlet.html#doPost%28javax.servlet.http.HttpServletRequest,%20javax.servlet.http.HttpServletResponse%29)方法,可以通过[HttpServletRequest#getParameter()](http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getParameter%28java.lang.String%29)获取post参数 -###触发HTTP请求的发送 +### 触发HTTP请求的发送 你可以显式地通过[URLConnection#connect()](http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html#connect%28%29)来发送请求,但是,当你调用获取响应信息的方法时,一样将自动发送请求。例如当你使用[URLConnection#getInputStream()](http://docs.oracle.com/javase/6/docs/api/java/net/URLConnection.html#getInputStream%28%29)时,就会自动触发请求,因此,connect()方法往往都是多余的。上面我的例子,也都是直接调用getInputStream()方法。 获取HTTP响应信息 @@ -98,7 +98,7 @@ else { ``` -###session的维护 +### session的维护 服务端session,通常是基于cookie实现的。你可以通过[CookieHandlerAPI](http://docs.oracle.com/javase/8/docs/api/java/net/CookieHandler.html)来管理cookie。在发送HTTP请求前,初始化一个[CookieManager](http://docs.oracle.com/javase/6/docs/api/java/net/CookieManager.html), 然后设置参数为[CookiePolicy](http://docs.oracle.com/javase/6/docs/api/java/net/CookiePolicy.html).[CCEPT_ALL](http://docs.oracle.com/javase/6/docs/api/java/net/CookiePolicy.html#ACCEPT_ALL)。 ```java // First set the default cookie manager. @@ -128,7 +128,7 @@ for (String cookie : cookies) { ``` 上面的split(";", 2)[0],作用是去掉一些跟服务端无关的cookie信息(例如expores,path等)。也可用cookie.substring(0, cookie.indexOf(';'))达到同样的目的 -###流的处理 +### 流的处理 不管你是否通过connection.setRequestProperty("Content-Length", contentLength)方法,为content设置了定长, [HttpURLConnection](http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html)在发送请求前,默认都会缓存整个请求的body。如果发送一个比较大的post请求(例如上传文件),有可能会导致OutOfMemoryException。为了避免这个问题,可以设置[HttpURLConnection#setFixedLengthStreamingMode()](http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html#setFixedLengthStreamingMode%28int%29) ```java httpConnection.setFixedLengthStreamingMode(contentLength); @@ -138,20 +138,20 @@ httpConnection.setFixedLengthStreamingMode(contentLength); httpConnection.setChunkedStreamingMode(1024); ``` -###User-Agent +### User-Agent 有时候,你发送的请求,可能只有在浏览器下才能正常返回,而其他方式却不行。这可能跟请求头中的User-Agent有关。通过URLConnection发送的请求,默认会带上的User-Agent信息是Java/1.6.0_19,也就是java+jre的版本。你可以重写这个信息: ```java connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.3) Gecko/20100401"); // Do as if you're using Firefox 3.6.3. ``` 这里有一份更全的浏览器[User-Agent清单](http://www.useragentstring.com/pages/useragentstring.php) -###错误处理 +### 错误处理 如果HTTP的响应码是4xx(客户端异常)或者5xx(服务端异常),你可以通过HttpURLConnection#getErrorStream()获取信息,服务端可能会将一些有用的错误信息放到这里面。 ```java InputStream error = ((HttpURLConnection) connection).getErrorStream(); ``` -###上传文件 +### 上传文件 一般来说,你需要将post的内容设为[multipart/form-data](http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2)(相关的RFC文档:[RFC2388](http://www.faqs.org/rfcs/rfc2388.html)) ```java String param = "value"; @@ -199,7 +199,7 @@ try ( 假设服务端还是一个[HttpServlet](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServlet.html),它的doPost()方法将会处理这个请求,服务端通过[HttpServletRequest#getPart()](http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html#getPart%28java.lang.String%29)获取你发送的内容(注意了,不是getParameter())。getPart()是个比较新的方法,是在Servlet 3.0后才引入的。如果你是Servlet 3.0之前的版本,则可以选用[Apache Commons FileUpload](http://commons.apache.org/fileupload]来解析multipart/form-data的请求。可以参考这里的[例子](http://stackoverflow.com/questions/2422468/upload-big-file-to-servlet/2424824#2424824) -###最后的话 +### 最后的话 上面啰嗦了很多,Apache提供了工具包,帮助我们更方便地完成这些事情 [Apache HttpComponents HttpClient](http://stackoverflow.com/questions/2422468/upload-big-file-to-servlet/2424824#2424824): - [HttpClient Tutorial](http://hc.apache.org/httpcomponents-client-ga/tutorial/html/) diff --git a/contents/what-is-a-serialversionuid-and-why-should-i-use-it.md b/contents/what-is-a-serialversionuid-and-why-should-i-use-it.md index 321c58a..25b448a 100644 --- a/contents/what-is-a-serialversionuid-and-why-should-i-use-it.md +++ b/contents/what-is-a-serialversionuid-and-why-should-i-use-it.md @@ -1,9 +1,9 @@ # serialVersionUID 有什么作用?该如何使用? -##问题 +## 问题 当一个对象实现 Serializable 接口时,多数 ide 会提示声明一个静态常量 serialVersionUID(版本标识),那 serialVersionUID 到底有什么作用呢?应该如何使用 serialVersionUID ? -##回答 +## 回答 serialVersionUID 是实现 Serializable 接口而来的,而 Serializable 则是应用于Java 对象序列化/反序列化。对象的序列化主要有两种用途: - 把对象序列化成字节码,保存到指定介质上(如磁盘等) diff --git a/contents/what-is-reflection-and-why-is-it-useful.md b/contents/what-is-reflection-and-why-is-it-useful.md index 1de0ef0..be81f0e 100644 --- a/contents/what-is-reflection-and-why-is-it-useful.md +++ b/contents/what-is-reflection-and-why-is-it-useful.md @@ -1,10 +1,10 @@ # 反射(reflection)是什么及其用途? -##问题描述 +## 问题描述 反射是什么,为什么它是有用的? 我特别感兴趣的是java,但我认为任何语言的原理都是相同的。 -##回答 +## 回答 反射的概念,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。在java中,通过反射,能够在"运行态"动态获得任意一个类的所有属性和方法,动态地调用对象的方法。 举个例子,假设你有一个不知道具体类的对象,并且你想调用它的"dosomething"方法(如果存在的话)。java的静态类型系统只能调用一个已知类对象对应的已知接口,在未指定对象类型时,无法调用它的方法。但是通过反射,你的代码能检查这个未知类对象,并试图找出这个dosomething方法。如果存在这个方法,你可以通过反射调用这个方法。 diff --git a/contents/what-is-the-difference-between-jsf-servlet-and-jsp.md b/contents/what-is-the-difference-between-jsf-servlet-and-jsp.md index 93a31c7..f84ab62 100644 --- a/contents/what-is-the-difference-between-jsf-servlet-and-jsp.md +++ b/contents/what-is-the-difference-between-jsf-servlet-and-jsp.md @@ -1,11 +1,11 @@ ## JSF, Servlet 和 JSP (三种技术)有什么区别? -###问题 +### 问题 JSP 和 Servlet 有什么关系?JSP 是某种 Servlet 吗?JSP 和 JSF 又有什么关系?JSF 是某种基于JSP的,预构建好的 UI 吗,像 ASP.NET-MVC 那样? -###回答1 +### 回答1 #### JSP(Java Server Pages) JSP 是一种运行在服务器上的Java 视图技术,它允许你写入模版化的文本(例如客户端代码 HTML, CSS, JavaScript等)。JSP 支持标签库(taglibs),标签库由Java 代码实现,让你可以动态地控制页面输出。JSTL 便是一种比较有名的标签库。JSP 同样支持表达式语言(expression language),表达式语言可以用来访问后台数据(页面上可用的属性,request/session 对象等等), 通常与标签库结合使用。 diff --git a/contents/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java.md b/contents/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java.md index f09120b..a6e96a9 100644 --- a/contents/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java.md +++ b/contents/what-issues-should-be-considered-when-overriding-equals-and-hashcode-in-java.md @@ -1,6 +1,6 @@ -##重写(Override)equals和hashCode方法时应考虑的问题 +## 重写(Override)equals和hashCode方法时应考虑的问题 -###理论上讲(编程语言、数学层面) +### 理论上讲(编程语言、数学层面) equals() 定义了对象的相等关系(自反性、对称性、传递性)(有点抽象,更详细说明,请参考[javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object))) 。 另外,它还具有一致性(也就是说,如果一个对象没有修改,那么对象的equals方法,应总是返回相同的值),此外,o.equals(null)应当总是返回false。 hashCode()([javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()))也必须具备一致性的(也就是说,如果equal的结果没有变,那么hashcode()也应总是返回相同的值) @@ -9,7 +9,7 @@ hashCode()([javadoc](http://docs.oracle.com/javase/7/docs/api/java/lang/Object **假如a.equals(b),那么a.hashCode() 应等于b.hashCode()** -###实践上讲 +### 实践上讲 **如果你重写了其中一个方法,那么务必重写另外一个方法** diff --git a/contents/when-to-use-linkedlist-over-arraylist.md b/contents/when-to-use-linkedlist-over-arraylist.md index 49cc0ae..60165ec 100644 --- a/contents/when-to-use-linkedlist-over-arraylist.md +++ b/contents/when-to-use-linkedlist-over-arraylist.md @@ -1,12 +1,12 @@ -##LinkedList、ArrayList各自的使用场景,如何确认应该用哪一个呢? +## LinkedList、ArrayList各自的使用场景,如何确认应该用哪一个呢? 一言以蔽之,在大部分情况下,使用ArrayList会好一些。 -###耗时上各有优缺点。ArrayList稍有优势 +### 耗时上各有优缺点。ArrayList稍有优势 List只是一个接口,而LinkedList、ArrayList是List的不同实现。LinkedList的模型是双向链表,而ArrayList则是动态数组 首先对比下常用操作的算法复杂度 -#####LinkedList +##### LinkedList - get(int index) : O(n) - add(E element) : O(1) - add(int index, E element) : O(n) @@ -14,7 +14,7 @@ List只是一个接口,而LinkedList、ArrayList是List的不同实现。Linke - Iterator.remove() : O(1) <--- LinkedList<E>的主要优点 - ListIterator.add(E element) is O(1) <--- LinkedList<E>的主要优点 -#####ArrayList +##### ArrayList - get(int index) : O(1) <--- ArrayList<E>的主要优点 - add(E element) : 基本是O(1) , 因为动态扩容的关系,最差时是 O(n) - add(int index, E element) : 基本是O( n - index) , 因为动态扩容的关系,最差时是 O(n) @@ -27,7 +27,7 @@ List只是一个接口,而LinkedList、ArrayList是List的不同实现。Linke **总之,get操作,ArrayList快一些。而add操作,两者差不多**。(除非是你希望在List中间插入节点,且维护了一个Iterator指向指定位置,这时候linkedList能快一些,但是,我们更多时候是直接在尾部插入节点,这种特例的情况并不多) -###空间占用上,ArrayList完胜 +### 空间占用上,ArrayList完胜 看下两者的内存占用图  diff --git a/contents/why-cant-i-switch-on-a-string.md b/contents/why-cant-i-switch-on-a-string.md index 140a662..ef9c3fb 100644 --- a/contents/why-cant-i-switch-on-a-string.md +++ b/contents/why-cant-i-switch-on-a-string.md @@ -1,11 +1,11 @@ # 为什么不能用string类型进行switch判断 -##问题描述 +## 问题描述 为什么不能用string类型进行switch判断? 在java的后续版本中,是否会增加这个新特性? 有人能给我一篇文章,解释一下为什么不能这样做,或者进一步说明java中switch语句的运行方式? -##回答 +## 回答 在switch语句中用string作为case,这个特性已经在java SE7 中被实现了,距离 [这个'bug'](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=1223179) 被提出至少也有16年了。为何迟迟不提供这个特性,原因不明。但可以推测,可能跟性能有关。 **Implementtation in JDK 7** diff --git a/contents/why-does-math-round0-49999999999999994-return-1.md b/contents/why-does-math-round0-49999999999999994-return-1.md index 6da947a..01f5f82 100644 --- a/contents/why-does-math-round0-49999999999999994-return-1.md +++ b/contents/why-does-math-round0-49999999999999994-return-1.md @@ -4,7 +4,7 @@ tags:stackoverflow-java-top-qa --- -###问题 +### 问题 通过下面的程序你可以看出来,对于任意一个比0.5略小的都是舍去小数向下取整,只有0.5是例外. ```java diff --git a/contents/why-does-math.round-(0.49999999999999994)-return-1.md b/contents/why-does-math.round-(0.49999999999999994)-return-1.md index fb7bf35..7cd7b5d 100644 --- a/contents/why-does-math.round-(0.49999999999999994)-return-1.md +++ b/contents/why-does-math.round-(0.49999999999999994)-return-1.md @@ -1,6 +1,6 @@ -##为什么Math.round(0.49999999999999994)返回1? +## 为什么Math.round(0.49999999999999994)返回1? -###问题描述: +### 问题描述: 在下面的程序中你可以看到每个稍微比.5小的值都被向下舍入了,除了`0.5`那个。 @@ -43,7 +43,7 @@ for (int i = 10; i >= 0; i--) { ``` 我使用 Java 6 update 31。 -###回答: +### 回答: **总结** diff --git a/contents/why-does-this-code-using-random-strings-print-hello-world.md b/contents/why-does-this-code-using-random-strings-print-hello-world.md index d1d4850..47ebfab 100644 --- a/contents/why-does-this-code-using-random-strings-print-hello-world.md +++ b/contents/why-does-this-code-using-random-strings-print-hello-world.md @@ -1,6 +1,6 @@ -##为什么以下用随机生成的文字会得出 “hello world”? +## 为什么以下用随机生成的文字会得出 “hello world”? -###问题 +### 问题 为什么以下用随机生成的文字会得出"hello world". 有人能解释一下吗? @@ -22,7 +22,7 @@ public static String randomString(int i) return sb.toString(); } ``` -###回答1(最佳) +### 回答1(最佳) 在JAVA 里面,随机类的实现不是真正的随机,是伪随机. 就是说如果随机类的种子是一样的话,他们会生成同一组的数字。 diff --git a/contents/why-is-printing-b-dramatically-slower-than-printing.md b/contents/why-is-printing-b-dramatically-slower-than-printing.md index 4887753..8971370 100644 --- a/contents/why-is-printing-b-dramatically-slower-than-printing.md +++ b/contents/why-is-printing-b-dramatically-slower-than-printing.md @@ -1,6 +1,6 @@ -##为什么打印B要比打印#慢很多? +## 为什么打印B要比打印#慢很多? -###问题 +### 问题 我生成了两个大小为 1000 * 1000 的矩阵 第一个矩阵:O和# 第二个矩阵:O和B @@ -43,7 +43,7 @@ for (int i = 0; i < 1000; i++) { - Netbeans 7.2,结果输出在IDE的控制台 - 使用`System.nanoTime()`度量时间 -###回答 +### 回答 纯推测:你正在使用的终端试图进行[“自动换行”(word-wrapping)](http://en.wikipedia.org/wiki/Word_wrap),而不是“字符换行”(character-wrapping),并且将'B'视为一个单词字符(word character),而'#'视为一个非单词字符(non-word character)。因此当输出到达行尾时,控制台搜索一个位置用来换行,当遇到'#'时可以立即执行换行;然而遇到'B'时,控制台必须继续搜索,并且可能有更多的字符需要换行(这个操作在一些控制台上可能花销很大,例如,输出退格,然后输出空白字符来覆盖那些需要被换行的字符)。 但是,这仅仅是理论推测。 diff --git a/contents/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result.md b/contents/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result.md index d436087..8468ad0 100644 --- a/contents/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result.md +++ b/contents/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result.md @@ -1,6 +1,6 @@ -##为什么这两个时间(1927年)相减会得到一个奇怪的结果? +## 为什么这两个时间(1927年)相减会得到一个奇怪的结果? -###问题描述 +### 问题描述 如果我运行如下的程序,将两个相距一秒的日期解析成字符串并比较他们。 ``` public static void main(String[] args) throws ParseException { @@ -48,7 +48,7 @@ lastRule=null] Locale(Locale.getDefault()): zh_CN ``` -###问题回答 +### 问题回答 这是因为1927年11月31日上海的时区改变了。 观看[此页](http://www.timeanddate.com/time/change/china/shanghai?year=1927)获得更多关于上海1927年的细节。 这个问题主要是由于在1927年12月31日的午夜,时钟回调了5分钟零52秒。