google code prettify

2013年10月1日 星期二

Java String、StringBuffer、StringBuilder的差別

1 String
String:字符串常量,字符串長度不可變。

2 StringBuffer
StringBuffer:字符串變量(Synchronized,即線程安全)。如果要頻繁對字符串內容進行修改,出於效率考慮最好使用StringBuffer,如果想轉成String類型,可以調用StringBuffer的toString()方法。
Java.lang.StringBuffer線程安全的可變字符序列。在任意時間點上它都包含某種特定的字符序列,但通過某些方法調用可以改變該序列的長度和內容。可將字符串緩沖區安全地用於多個線程。
StringBuffer 上的主要操作是 append 和 insert 方法,可重載這些方法,以接受任意類型的數據。每個方法都能有效地將?定的數據轉換成字符串,然後將該字符串的字符追加或插入到字符串緩沖區中。append 方法始終將這些字符添加到緩沖區的末端;而 insert 方法則在指定的點添加字符。例如,如果 z 引用一個當前內容是“start”的字符串緩沖區對象,則此方法調用 z.append("le") 會使字符串緩沖區包含“startle”,而 z.insert(4, "le") 將更改字符串緩沖區,使之包含“starlet”。

3 StringBuilder
StringBuilder:字符串變量(非線程安全)。
java.lang.StringBuilder是一個可變的字符序列,是JDK5.0新增的。此類提供一個與 StringBuffer 兼容的 API,但不保證同步。該類被設計用作 StringBuffer 的一個簡易替換,用在字符串緩沖區被單個線程使用的時候(這種情況很普遍)。如果可能,建議優先采用該類,因?在大多數實現中,它比 StringBuffer 要快。兩者的方法基本相同。
在大部分情況下,StringBuilder > StringBuffer。

4 三者區別
String 類型和StringBuffer的主要性能區別:String是不可變的對象, 因此在每次對 String 類型進行改變的時候,都會生成一個新的 String 對象,然後將指針指向新的 String 對象,所以經常改變內容的字符串最好不要用 String ,因?每次生成對象都會對系統性能產生影響,特別當內存中無引用對象多了以後, JVM 的 GC 就會開始工作,性能就會降低。
使用 StringBuffer 類時,每次都會對 StringBuffer 對象本身進行操作,而不是生成新的對象並改變對象引用。所以多數情況下推薦使用 StringBuffer ,特別是字符串對象經常改變的情況下。
在某些特別情況下, String 對象的字符串拼接其實是被 JVM 解釋成了 StringBuffer 對象的拼接,所以這些時候 String 對象的速度並不會比 StringBuffer 對象慢,例如:
 String S1 = “This is only a” + “ simple” + “ test”;
 StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

生成 String S1 對象的速度並不比 StringBuffer慢。其實在 JVM 裏,自動做了如下轉換:
 String S1 = “This is only a” + “ simple” + “test”; 
JVM直接把上述語句當作:
String S1 = “This is only a simple test”;
所以速度很快。但要注意的是,如果拼接的字符串來自另外的String對象的話,JVM就不會自動轉換了,速度也就沒那麼快了,例如:

String S2 = “This is only a”;
String S3 = “ simple”;
String S4 = “ test”;
String S1 = S2 +S3 + S4;

這時候,JVM 會規規矩矩的按照原來的方式去做。
在大部分情況下,StringBuffer > String。

5 使用策略
(1)基本原則:如果要操作少量的數據,用String ;單線程操作大量數據,用StringBuilder ;多線程操作大量數據,用StringBuffer。
(2)不要使用String類的"+"來進行頻繁的拼接,因?那?的性能極差的,應該使用StringBuffer或StringBuilder類,這在Java的優化上是一條比較重要的原則。舉個例子:在使用String 的時候,拼接字符串時使用“+”在JVM上形成臨時的StringBuffer對象,同時在每一個字符串上都建立一個對象,拼接了兩個字符串一共需要創建4個對象!(一個保存結果的String,兩個字符串對象,一個臨時的StringBuffer對象)。而使用StringBuffer的話,只需創建2個對象!一個StringBuffer對象和保存最後結果的的String對象 。
(3)?了獲得更好的性能,在構造 StirngBuffer 或 StirngBuilder 時應盡可能指定它們的容量。當然,如果你操作的字符串長度不超過 16 個字符就不用了。不指定容量會顯著降低性能。
(4)StringBuilder一般使用在方法內部來完成類似"+"功能,因?是線程不安全的,所以用完以後可以丟棄。StringBuffer主要用在全局變量中。
(5)相同情況下使用 StirngBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升,但卻要冒多線程不安全的風險。而在現實的模塊化編程中,負責某一模塊的程序員不一定能清晰地判斷該模塊是否會放入多線程的環境中運行,因此:除非確定系統的瓶頸是在 StringBuffer 上,並且確定你的模塊不會運行在多線程模式下,才可以采用StringBuilder;否則還是用StringBuffer。

資料來源:http://rritw.com/a/JAVAbiancheng/JAVAzonghe/20130702/377964.html

Java 取得WEB-INF/classes 的實體路徑位置

一般來說在Servlet中就可以取得WEB-INF的位置
但是我的需求是要在init DB connection時,就要取得實體路徑去抓取相關的檔案
所以就能用別的手法了

程式如下:
ClassLoader cl = this.getClass().getClassLoader();
String path = cl.getResource("/").getPath();
System.out.println("this path:" + path);

印出來的路徑如下:
this path:/D:/eclipse/workspace/CBCAdmin/javagip/WEB-INF/classes/

Jacob使用

Jacob(Java-Com Bridge)
簡單來說,就是用Java呼叫COM元件的API
Jar檔下載位置:http://sourceforge.net/projects/jacob-project/
下方的範例程式:https://github.com/sabaao/sabaao/commit/d84a8df15fcb15e3106de9929aa9291592b986d8

而在使用時注意dll跟jar檔一定要是相同的版本,不然可能會出錯

以下為使用步驟(我使用的版本是1.14.3):
Step1:jacob-1.14.3-x64.dlljacob-1.14.3-x86.dll放置於C:\Windows\System32\

Step2:注冊你要使用的元件(檔案路徑依情況作修改)

REGSVCS D:\ConnStrManage\ConnStrForJava\ComSecureCnnStr.dll
GACUTIL /i D:\ConnStrManage\ConnStrForJava\ComSecureCnnStr.dll
















Gacutil.exeRegsvcs.exe可以下列位置取得:
      Gacutil.exe=>C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\x64
      Regsvcs.exe=>C:\Windows\Microsoft.NET\Framework\v2.0.50727

Step3:於專案中加入jacob.jar參考

Util如下:

package tw.cbc.jacob;

import com.jacob.com.Dispatch;


public class Jacob {

private String dispatchName;
private String methodName;
private Object[] params;

private Dispatch dispatch;
public Jacob(String dispatchName){
this.dispatchName = dispatchName;
dispatch = new Dispatch(this.dispatchName);
}

public Jacob(String dispatchName,String methodName,Object[] params){
this.dispatchName = dispatchName;
this.methodName = methodName;
this.dispatch = new Dispatch(this.dispatchName);
this.params = params;
}
public String getDispatchName() {
return dispatchName;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}


public Object[] getParams() {

return params;
}

public void setParams(Object[] params) {

this.params = params;
}

public Dispatch getDispatch() {

return dispatch;
}

public Object call(){
Object obj = null;
if(params==null){
obj = Dispatch.call(this.dispatch,this.methodName);
}else if(params.length==0){
obj = Dispatch.call(this.dispatch,this.methodName);
}else if(params.length==1){
obj = Dispatch.call(this.dispatch,this.methodName,params[0]);
}else if(params.length==2){
obj = Dispatch.call(this.dispatch,this.methodName,params[0],params[1]);
}else if(params.length==3){
obj = Dispatch.call(this.dispatch,this.methodName,params[0],params[1],params[2]);
}else if(params.length==4){
obj = Dispatch.call(this.dispatch,this.methodName,params[0],params[1],params[2],params[3]);
}else if(params.length==5){
obj = Dispatch.call(this.dispatch,this.methodName,params[0],params[1],params[2],params[3],params[4]);
}else if(params.length==6){
obj = Dispatch.call(this.dispatch,this.methodName,params[0],params[1],params[2],params[3],params[4],params[5]);
}else if(params.length==7){
obj = Dispatch.call(this.dispatch,this.methodName,params[0],params[1],params[2],params[3],params[4],params[5],params[6]);
}else if(params.length==8){
obj = Dispatch.call(this.dispatch,this.methodName,params[0],params[1],params[2],params[3],params[4],params[5],params[6],params[7]);
}
return obj;
}
}

呼叫範例:
Jacob jacob = new Jacob("SecureCnnStr");
jacob.setMethodName("EntSecurCnnStr");
jacob.setParams(new Object[]{"SOD","D:\\CBC\\encode\\","IBPS1455"});
jacob.call();
jacob.setMethodName("GetConnStr");
jacob.setParams(null);
String result = jacob.call().toString();