1、String 和StringBuffer,StringBuilder的區別
String類提供了數值不可改變的字符串。
StringBuffer類提供的字符串進行修改。可以使用StringBuffers來動態構造字符數據。
StringBuilder相對StringBuffer是線程安全的.

2、String是最基本的數據類型嗎?
基本數據類型包括byte、int、char、long、float、double、boolean和short。
java.lang.String類是final類型的,因此不可以繼承這個類、不能修改這個類。對字符串的任何修改,都將生成一個新的字符串。
當進行大量的字符串連接時,為了提高效率節省空間,我們應該用StringBuffer類

3、説出ArrayList,Vector, LinkedList的存儲性能和特性 ?
ArrayList和Vector都是使用數組方式存儲數據,此數組元素數大於實際存儲的數據以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及數組元素移動等內存操作,所以索引數據快而插入數據慢,Vector由於使用了synchronized方法(線程安全),通常性能上較ArrayList差,而LinkedList使用雙向鏈表實現存儲,按序號索引數據需要進行前向或後向遍歷,但是插入數據時只需要記錄本項的前後項即可,所以插入速度較快。

4、ArrayList和Vector的區別,HashMap和Hashtable的區別
答:就ArrayList與Vector主要從二方面來説.
一.同步性:Vector是線程安全的,也就是説是同步的,而ArrayList是線程序不安全的,不是同步的
二.數據增長:當需要增長時,Vector默認增長為原來一培,而ArrayList卻是原來的一半
就HashMap與HashTable主要從三方面來説。
一.歷史原因:Hashtable是基於陳舊的Dictionary類的,HashMap是Java 1.2引進的Map接口的一個實現
二.同步性:Hashtable是線程安全的,也就是説是同步的,而HashMap是線程序不安全的,不是同步的
三.值:只有HashMap可以讓你將空值作為一個表的條目的key或value

5、介紹JAVA中的Collection FrameWork(包括如何寫自己的數據結構)?
答:Collection FrameWork如下:
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection是最基本的集合接口,一個Collection代表一組Object,即Collection的元素(Elements)
Map提供key到value的映射

6、Collection 和 Collections的區別。
  Collections是個java.util下的類,它包含有各種有關集合操作的靜態方法。
  Collection是個java.util下的接口,它是各種集合結構的父接口。

7、int 和 Integer 有什麼區別?
Java 提供兩種不同的類型:引用類型和原始類型(或內置類型)。
int是java的原始數據類型,Integer是java為int提供的封裝類。Java為每個原始類型提供了封裝類。
原始類型 封裝類
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double
所有的封裝類都是不能改變的,任何變動都將生成一個新的類。
對於數字特殊,系統為了提高效率,對於小於128的數字進行了內部緩衝,所以2個120的數字Integer有可能地址相等。
引用類型和原始類型的行為完全不同,並且它們具有不同的語義。引用類型和原始類型具有不同的特徵和用法,它們包括:大小和速度問題,這種類型以哪種類型的數據結構存儲,當引用類型和原始類型用作某個類的實例數據時所指定的缺省值。對象引用實例變量的缺省值為 null,而原始類型實例變量的缺省值與它們的類型有關。
從JDK5.0開始,原始類和包裝類可以自動進行轉換,我們可以在絕大部分int的地方使用Integer了.

8、下面哪些類可以被繼承?

   java.lang.Thread (T)
   java.lang.Number (T)
   java.lang.Double (F)
   java.lang.Math (F)
   java.lang.Void (F)
   java.lang.Class (F)
   java.lang.ClassLoader (T)


9、面向對象的特徵有哪些方面?
抽象:抽象就是忽略一個主題中與當前目標無關的那些方面,以便更充分地注意與當前目標有關的方面。抽象並不打算了解全部問題,而只是選擇其中的一部分,暫時不用部分細節。抽象包括兩個方面,一是過程抽象,二是數據抽象。
繼承:繼承是一種聯結類的層次模型,並且允許和鼓勵類的重用,它提供了一種明確表述共性的方法。對象的一個新類可以從現有的類中派生,這個過程稱為類繼承。新類繼承了原始類的特性,新類稱為原始類的派生類(子類),而原始類稱為新類的基類(父類)。派生類可以從它的基類那裏繼承方法和實例變量,並且類可以修改或增加新的方法使之更適合特殊的需要。
封裝:封裝是把過程和數據包圍起來,對數據的訪問只能通過已定義的界面。面向對象計算始於這個基本概念,即現實世界可以被描繪成一系列完全自治、封裝的對象,這些對象通過一個受保護的接口訪問其他對象。

10、String s = "a" + "b" + "c" + "d" + "e"; 問此語句共創建了幾個對象?
1個。
編譯器編譯的時候就處理為"abcde"了 。
就創建了一個
String s = "a" + "b" + "c" + "d" + "e";
賦值符號右邊的"a"、"b"、"c"、"d"、"e"都是常量
對於常量,編譯時就直接存儲它們的字面值而不是它們的引用
在編譯時就直接講它們連接的結果提取出來變成了"abcde"
該語句在class文件中就相當於String s = "abcde"
然後當JVM執行到這一句的時候, 就在String pool裏找
如果沒有這個字符串,就會產生一個

11、String s = new String("xyz");創建了幾個String Object?
  兩個對象,一個是“xyx”,一個是指向“xyx”的引用對象s。

12、Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
  Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;

13、short s1 = 1; s1 = s1 + 1;有什麼錯? short s1 = 1; s1 += 1;有什麼錯?
  short s1 = 1; s1 = s1 + 1;有錯,s1是short型,s1+1是int型,不能顯式轉化為short型。可修改為
s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正確。


14、在使用interface聲明一個接口時,只可以使用( D)修飾符修飾該接口。
A、private B、protected C、private protected D、public

15、有以下方法的定義,請選擇該方法的返回類型( D)。
ReturnType method(byte x, float y)
{
  return (short)x/y*2;
}
A、byte B、short C、int D、float
因為參數裏有一個float

16、在編寫Java Applet程序時,需要在程序的開頭寫上(B )語句。
A、import java.awt.* ; B、import java.applet.* ;
C、import java.io.* ; D、import java.awt.event.* ;

17、C++或Java中的異常處理機制的簡單原理和應用。
當JAVA程序違反了JAVA的語義規則時,JAVA虛擬機就會將發生的錯誤表示為一個異常。違反語義規則包括
2種情況。一種是JAVA類庫內置的語義檢查。例如數組下標越界,會引發IndexOutOfBoundsException;訪問
null的對象時會引發NullPointerException。另一種情況就是JAVA允許程序員擴展這種語義檢查,程序員
可以創建自己的異常,並自由選擇在何時用throw關鍵字引發異常。所有的異常都是java.lang.Thowable
的子類。

18、Java中所有的類都繼承了java.lang.Object類,而在C++中沒有像java.lang.Object這樣的類,這是為什麼呢?都是面向對象,Java這樣做有什麼好處呢?
解析:Java採用的是單根結構,所有的類都繼承了java.lang.Object類。對於Java這種純面向對象的語言來説,這種設計具有很好的靈活性,比如對垃圾收集來説很有利,所有的類都具有java.lang.Object類具有的方法等。C++沒有更多這樣的方法,大概是為了向後兼容。向C兼容,滿足它設計上最大的靈活性。
C++面向對象的部分會去考慮"和C兼容"?舉個例子,MFC裏面雖然不是完全的單根結構,基本也算基於CObject構建了一個類層次結構吧?懂點C++的人也應該知道可以給它增加垃圾回收器吧?跟單根結構有什麼關係?再説C++0x也會引入一個可選的垃圾回收器了
答案:C++的特點是指針,一個指針可以指向任何的對象、結構、基本類型、函數。強,估計到處是void*才行
Java沒有指針類型,所以Java用Object基礎類的共同特徵來實現所有對象類型之間的轉換。

18、對象與實例有什麼區別?
解析:在Java的內存分配中,對象和實例是不同的,前者分配在內存堆裏,後者分配在堆棧裏,至於為什麼要這樣分,參考一下其他的資料。對象是不變的東西,它是對客觀事物的抽象,實例是對操作對象的引用,你不能直接操作對象。
答案:對象和實例從宏觀的角度看,區別是:對象是同類事物的一種抽象表現形式,而實例是對象的具體化,一個對象可以實例化很多實例,對象就是一個模型,實例是照着這個模型生產的最終產品。實際上就是這樣,一個對象可以實例化N個實例。就像根據一個模型可以製造多個實際的產品一樣。
從內存分配的角度來看,對象是保存在堆中的,而實例是存儲在棧中的,實例其實只是對象的一個引用,也就是指向對象的指針。
新鮮吧,原來對象和實例還有這麼大的差別,估計你要這麼跟面試的人解釋,走先!

20. Error與Exception有什麼區別?
Error表示系統級的錯誤和程序不必處理的異常,
Exception表示需要捕捉或者需要程序進行處理的異常。

21、HashMap如何變成線程安全的?
Map m = Collections.synchronizedMap(new HashMap(...)); 

22、作用域public,private,protected,以及不寫時的區別
答:區別如下:
作用域           當前類       同一package  子孫類       其他package
public            √              √                  √             √
protected        √              √                  √             ×
friendly          √              √                   ×            ×
private           √              ×                   ×            ×
不寫時默認為friendly

23、char型變量中能不能存貯一箇中文漢字?為什麼?
答:是能夠定義成為一箇中文的,因為java中以unicode編碼,一個char佔16個字節,所以放一箇中文是沒問題的

24、float型float f=3.4是否正確?
答:不正確。精度不準確,應該用強制類型轉換,如下所示:float f=(float)3.4


25、抽象類和接口的區別

  (1)接口可以被多重implements,抽象類只能被單一extends
  (2)接口只有定義,只是一種標識,抽象類可以有定義和實現
  (3)接口的字段定義默認為:public static final, 抽象類字段默認是"friendly"(本包可見)

26、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?
  都不能

27、接口是否可繼承接口? 抽象類是否可實現(implements)接口? 抽象類是否可繼承實體類(concrete
class)?
  接口可以繼承接口。抽象類可以實現(implements)接口,抽象類是否可繼承實體類,但前提是實體類
必須有明確的構造函數。


28、J2EE是什麼?
答:Je22是Sun公司提出的多層(multi-diered),分佈式(distributed),基於組件(component-base)的企業級應用模型(enterpriese application model).在這樣的一個應用系統中,可按照功能劃分為不同的組件,這些組件又可在不同計算機上,並且處於相應的層次(tier)中。所屬層次包括客户層(clietn tier)組件,web層和組件,Business層和組件,企業信息系統(EIS)層。

29、談談final, finally, finalize的區別。
  final?修飾符(關鍵字)如果一個類被聲明為final,意味着它不能再派生出新的子類,不能作為父
類被繼承。因此一個類不能既被聲明為 abstract的,又被聲明為final的。將變量或方法聲明為final,
可以保證它們在使用中不被改變。被聲明為final的變量必須在聲明時給定初值,而在以後的引用中只能
讀取,不可修改。被聲明為final的方法也同樣只能使用,不能重載。
  finally?再異常處理時提供 finally 塊來執行任何清除操作。如果拋出一個異常,那麼相匹配的
catch 子句就會執行,然後控制就會進入 finally 塊(如果有的話)。
  finalize?方法名。Java 技術允許使用 finalize() 方法在垃圾收集器將對象從內存中清除出去之前
做必要的清理工作。這個方法是由垃圾收集器在確定這個對象沒有被引用時對這個對象調用的。它是在
Object 類中定義的,因此所有的類都繼承了它。子類覆蓋 finalize() 方法以整理系統資源或者執行其
他清理工作。finalize() 方法是在垃圾收集器刪除對象之前對這個對象調用的。

30、Anonymous Inner Class (匿名內部類) 是否可以extends(繼承)其它類,是否可以implements(實
現)interface(接口)?
  匿名的內部類是沒有名字的內部類。不能extends(繼承) 其它類,但一個內部類可以作為一個接口,
由另一個內部類實現。
 
31、Static Nested Class 和 Inner Class的不同,説得越多越好(面試題有的很籠統)。
  Nested Class (一般是C++的説法),Inner Class (一般是JAVA的説法)。Java內部類與C++嵌套類
最大的不同就在於是否有指向外部的引用上。具體可見http:
//www.frontfree.net/articles/services/view.asp?id=704&page=1
  注: 靜態內部類(Inner Class)意味着1創建一個static內部類的對象,不需要一個外部類對象,2
不能從一個static內部類的一個對象訪問一個外部類對象
第四,&和&&的區別。
  &是位運算符。&&是布爾邏輯運算符。

32、什麼時候用assert。
  斷言是一個包含布爾表達式的語句,在執行這個語句時假定該表達式為 true。如果表達式計算為
false,那麼系統會報告一個 Assertionerror。它用於調試目的:
assert(a > 0); // throws an Assertionerror if a <= 0
斷言可以有兩種形式:
assert Expression1 ;
assert Expression1 : Expression2 ;
  Expression1 應該總是產生一個布爾值。
  Expression2 可以是得出一個值的任意表達式。這個值用於生成顯示更多調試信息的 String 消息。
  斷言在默認情況下是禁用的。要在編譯時啓用斷言,需要使用 source 1.4 標記:
  javac -source 1.4 Test.java
  要在運行時啓用斷言,可使用 -enableassertions 或者 -ea 標記。
  要在運行時選擇禁用斷言,可使用 -da 或者 -disableassertions 標記。
  要系統類中啓用斷言,可使用 -esa 或者 -dsa 標記。還可以在包的基礎上啓用或者禁用斷言。
  可以在預計正常情況下不會到達的任何位置上放置斷言。斷言可以用於驗證傳遞給私有方法的參數。
不過,斷言不應該用於驗證傳遞給公有方法的參數,因為不管是否啓用了斷言,公有方法都必須檢查其參
數。不過,既可以在公有方法中,也可以在非公有方法中利用斷言測試後置條件。另外,斷言不應該以任
何方式改變程序的狀態。

33、GC是什麼? 為什麼要有GC? (基礎)。
  GC是垃圾收集器。Java 程序員不用擔心內存管理,因為垃圾收集器會自動進行管理。要請求垃圾收
集,可以調用下面的方法之一:
System.gc()
Runtime.getRuntime().gc()

34、多線程有幾種實現方法,都是什麼?同步有幾種實現方法,都是什麼?
答:多線程有兩種實現方法,分別是繼承Thread類與實現Runnable接口
同步的實現方面有兩種,分別是synchronized,wait與notify

35、sleep() 和 wait() 有什麼區別? 搞線程的最愛
  sleep()方法是使線程停止一段時間的方法。在sleep 時間間隔期滿後,線程不一定立即恢復執行。
這是因為在那個時刻,其它線程可能正在運行而且沒有被調度為放棄執行,除非(a)“醒來”的線程具有
更高的優先級 (b)正在運行的線程因為其它原因而阻塞。
  wait()是線程交互時,如果線程對一個同步對象x 發出一個wait()調用,該線程會暫停執行,被調對
象進入等待狀態,直到被喚醒或等待時間到。

36、啓動一個線程是用run()還是start()?
  啓動一個線程是調用start()方法,使線程所代表的虛擬處理機處於可運行狀態,這意味着它可以由
JVM調度並執行。這並不意味着線程就會立即運行。run()方法可以產生必須退出的標誌來停止一個線程。

37、當一個線程進入一個對象的一個synchronized方法後,其它線程是否可進入此對象的其它方法?
  不能,一個對象的一個synchronized方法只能由一個線程訪問。


38、數組有沒有length()這個方法? String有沒有length()這個方法?
  數組沒有length()這個方法,有length的屬性。
  String有有length()這個方法。

39、Overload和Override的區別。Overloaded的方法是否可以改變返回值的類型?
  方法的重寫Overriding和重載Overloading是Java多態性的不同表現。重寫Overriding是父類與子類
之間多態性的一種表現,重載Overloading是一個類中多態性的一種表現。如果在子類中定義某方法與其
父類有相同的名稱和參數,我們説該方法被重寫 (Overriding)。子類的對象使用這個方法時,將調用子
類中的定義,對它而言,父類中的定義如同被“屏蔽”了。如果在一個類中定義了多個同名的方法,它們
或有不同的參數個數或有不同的參數類型,則稱為方法的重載(Overloading)。Overloaded的方法是可以
改變返回值的類型。

40、Set裏的元素是不能重複的,那麼用什麼方法來區分重複與否呢? 是用==還是equals()? 它們有何區
別?
  Set裏的元素是不能重複的,那麼用iterator()方法來區分重複與否。equals()是判讀兩個Set是否相
等。
  equals()和==方法決定引用值是否指向同一對象equals()在類中被覆蓋,為的是當兩個分離的對象的
內容和類型相配的話,返回真值。

41、給我一個你最常見到的runtime exception。
ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException,
CannotRedoException, CannotUndoException, ClassCastException, CMMException,
ConcurrentModificationException, DOMException, EmptyStackException,
IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException,
IllegalStateException,
ImagingOpException, IndexOutOfBoundsException, MissingResourceException,
NegativeArraySizeException, NoSuchElementException, NullPointerException,
ProfileDataException, ProviderException, RasterFORMatException, SecurityException,
SystemException, UndeclaredThrowableException, UnmodifiableSetException,
UnsupportedOperationException

42、構造器Constructor是否可被override?
  構造器Constructor不能被繼承,因此不能重寫Overriding,但可以被重載Overloading。

43、try {}裏有一個return語句,那麼緊跟在這個try後的finally {}裏的code會不會被執行,什麼時候
被執行,在return前還是後?
  會執行,在return前執行。

44、編程題: 用最有效率的方法算出2乘以8等於幾?
  有C背景的程序員特別喜歡問這種問題。
  2 << 3

45、兩個對象值相同(x.equals(y) == true),但卻可有不同的hash code,這句話對不對?
  不對,有相同的hash code。

46、當一個對象被當作參數傳遞到一個方法後,此方法可改變這個對象的屬性,並可返回變化後的結果,
那麼這裏到底是值傳遞還是引用傳遞?
  是值傳遞。Java 編程語言只由值傳遞參數。當一個對象實例作為一個參數被傳遞到方法中時,參數
的值就是對該對象的引用。對象的內容可以在被調用的方法中改變,但對象的引用是永遠不會改變的。

47、swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上?
  switch(expr1)中,expr1是一個整數表達式。因此傳遞給 switch 和 case 語句的參數應該是 int
、 short、 char 或者 byte。long,string 都不能作用於swtich。

48、Java實現 字符串到實數轉化的偽代碼
  public double GetDouble(
String Dtr,//轉換目標
int len//小數位長度
)
  Eg GetDouble(“123456.3456”,2) = 123456.35

public double GetDouble(String Dtr, int len) {  
  DecimalFormat nf = new DecimalFormat("#.##");  
  try {  
    return Double.parseDouble(nf.format(nf.parse(Dtr)));  
  } catch (ParseException e) {  
    e.printStackTrace();  
    return Double.MIN_VALUE;  
  }  

49、指出下面程序的運行結果:

class A{
static{
System.out.print("1");
}
public A(){
System.out.print("2");
}
}
class B extends A{
static{
System.out.print("a");
}
public B(){
System.out.print("b");
}
}
public class Hello{
public static void main(String[] ars){
A ab = new B(); //執行到此處,結果: 1a2b
ab = new B(); //執行到此處,結果: 1a2bab

50、用JAVA實現一種排序,JAVA類實現序列化的方法(二種)? 如在COLLECTION框架中,實現比較要實現什麼樣的接口?
答:用插入法進行排序代碼如下
package test;
import java.util.*;
class  InsertSort
{
 ArrayList al;
 public InsertSort(int num,int mod)
 {
  al = new ArrayList(num);
  Random rand = new Random();
  System.out.println("The ArrayList Sort Before:");
  for (int i=0;i  {
   al.add(new Integer(Math.abs(rand.nextInt()) % mod + 1));
   System.out.println("al["+i+"]="+al.get(i));
  }
 }
 public void SortIt()
 {
  Integer tempInt;
  int MaxSize=1;
  for(int i=1;i  {
       tempInt = (Integer)al.remove(i);
    if(tempInt.intValue()>=((Integer)al.get(MaxSize-1)).intValue())
    {
     al.add(MaxSize,tempInt);
     MaxSize++;
     System.out.println(al.toString());
    } else {
     for (int j=0;j     {
      if

(((Integer)al.get(j)).intValue()>=tempInt.intValue())
      {
       al.add(j,tempInt);
       MaxSize++;
       System.out.println(al.toString());
       break;
      }
     }
    }
  }
  System.out.println("The ArrayList Sort After:");
  for(int i=0;i  {
   System.out.println("al["+i+"]="+al.get(i));
  }
 }
 public static void main(String[] args)
 {
  InsertSort is = new InsertSort(10,100);
  is.SortIt();
 }
}
JAVA類實現序例化的方法是實現java.io.Serializable接口
Collection框架中實現比較要實現Comparable 接口和 Comparator 接口

51、內部類的實現方式?
答:示例代碼如下:
package test;
public class  OuterClass
{
 private class InterClass
 {
  public InterClass()
  {
   System.out.println("InterClass Create");
  }
 }
 public OuterClass()
 {
  InterClass ic = new InterClass();
  System.out.println("OuterClass Create");
 }
 public static void main(String[] args)
 {
  OuterClass oc = new OuterClass();
 }
}
輸出結果:
C:\>java test/OuterClass
InterClass Create
OuterClass Create
再一個例題:
public class OuterClass {
  private double d1 = 1.0;
    //insert code here
}
You need to insert an inner class declaration at line 3. Which two inner class declarations are

valid?(Choose two.)
A. class InnerOne{
     public static double methoda() {return d1;}
   }
B. public class InnerOne{
     static double methoda() {return d1;}
   }
C. private class InnerOne{
     double methoda() {return d1;}
   }
D. static class InnerOne{
     protected double methoda() {return d1;}
   }
E. abstract class InnerOne{
     public abstract double methoda();
   }
説明如下:
一.靜態內部類可以有靜態成員,而非靜態內部類則不能有靜態成員。 故 A、B 錯
二.靜態內部類的非靜態成員可以訪問外部類的靜態變量,而不可訪問外部類的非靜態變量;return d1 出錯。

故 D 錯
三.非靜態內部類的非靜態成員可以訪問外部類的非靜態變量。 故 C 正確
四.答案為C、E

52、面的程序輸出什麼?請用腦袋想,不要去編譯執行。 
public class T {
  public static void main(String[] args) {
    certkiller("four");
    certkiller("tee");
    certkiller("to");
  }

  public static void certkiller(String str) {

    int check = 4;
    if (check = str.length()) {
      System.out.print(str.charAt(check -= 1) + " ");
    } else {
      System.out.print(str.charAt(0) + " ");
    }
  }
}

53、靜態內部類的測試題與詳細分析
代碼
public class T {
  static class t1 {
    int i = 5;

    public int printA() {
      return i;
    }
  }

  static class t2 extends t1 {
    int i = 100;

    public int printB() {
      return i;
    }

    public void printC() {
      {
        System.out.println(super.i);
      }
    }
  }

  public static void main(String... args) {
    t1 t = new t1();
    t2 tt = new t2();
    tt.printC();
    System.out.println(tt.printB());
    System.out.println(t.printA());
    System.out.println(tt.printA());
    t1 ttt = (t1) tt;
    System.out.println(ttt.printA());
  }

}
問題
請寫出它的輸出結果:
  先把結果寫下,在自己編譯運行看看正確與否……
答案:
5
100
5
5
5
分析:
    tt.printC();
 //這個調用的是子類的方法,裏面輸出的是super.i 所以輸出為5
    System.out.println(tt.printB());
//這個調用子類方法,輸出i, 所以為 100
    System.out.println(t.printA());
// 這個是父類的方法,當然輸出5
    System.out.println(tt.printA());
// 這個是子類調用了繼承自父類的方法,不過裏面的i並沒有繼承關係,所以
// 代碼裏使用的依然是父類的 i,所以輸出依然是5
    t1 ttt = (t1) tt;
    System.out.println(ttt.printA());
// 多態的表現
// 但是變量 i 並沒有繼承關係,所以 父類的方法依然使用的是自己的變量i
// 輸出還是5

54、編程題: 寫一個Singleton出來。
  Singleton模式主要作用是保證在Java應用程序中,一個類Class只有一個實例存在。
  一般Singleton模式通常有幾種種形式:
  第一種形式:定義一個類,它的構造函數為private的,它有一個static的private的該類變量,在類
初始化時實例話,通過一個public的getInstance方法獲取對它的引用,繼而調用其中的方法。
public class Singleton {
  private Singleton(){}
  //在自己內部定義自己一個實例,是不是很奇怪?
  //注意這是private 只供內部調用
  private static Singleton instance = new Singleton();
  //這裏提供了一個供外部訪問本class的靜態方法,可以直接訪問  
  public static Singleton getInstance() {
    return instance;   
   }
}
 
  第二種形式:
public class Singleton {
  private static Singleton instance = null;
  public static synchronized Singleton getInstance() {
  //這個方法比上面有所改進,不用每次都進行生成對象,只是第一次     
  //使用時生成實例,提高了效率!
  if (instance==null)
    instance=new Singleton();
return instance;   }
}
其他形式:
  定義一個類,它的構造函數為private的,所有方法為static的。
  一般認為第一種形式要更加安全些