天天看點

JAVA常見面試題及解答

JAVA常見面試題及解答(精華)  

1)transient和volatile是java關鍵字嗎?(瞬聯)

如果用transient聲明一個執行個體變量,當對象存儲時,它的值不需要維持。例如:

class T

{   

      transient int a;  //不需要維持

      int b;  //需要維持

}  

這裡,如果T類的一個對象寫入一個持久的存儲區域,a的内容不被儲存,但b的将被儲存。

volatile修飾符告訴編譯器被volatile修飾的變量可以被程式的其他部分改變。在多線程程式中,有時兩個或更多的線程共享一個相同的執行個體變量。考慮效率問題,每個線程可以自己儲存該共享變量的私有拷貝。實際的變量副本在不同的時候更新,如當進入synchronized方法時。 用strictfp修飾類或方法,可以確定浮點運算(以及所有切斷)正如早期的Java版本那樣準确。切斷隻影響某些操作的指數。當一個類被strictfp修飾,所有的方法自動被strictfp修飾。

strictfp的意思是FP-strict,也就是說精确浮點的意思。在Java虛拟機進行浮點運算時,如果沒有指定strictfp關鍵字時,Java的編譯器以及運作環境在對浮點運算的表達式是采取一種近似于我行我素的行為來完成這些操作,以緻于得到的結果往往無法令你滿意。而一旦使用了strictfp來聲明一個類、接口或者方法時,那麼所聲明的範圍内Java的編譯器以及運作環境會完全依照浮點規範IEEE-754來執行。是以如果你想讓你的浮點運算更加精确,而且不會因為不同的硬體平台所執行的結果不一緻的話,那就請用關鍵字strictfp。

你可以将一個類、接口以及方法聲明為strictfp,但是不允許對接口中的方法以及構造函數聲明strictfp關鍵字,例如下面的代碼:

strictfp interface A {}

public strictfp class FpDemo1 {   

      strictfp void f() {}   

}  

2. 錯誤的使用方法

interface A {   

    strictfp void f();   

}   

public class FpDemo2 {   

    strictfp FpDemo2() {}   

}

一旦使用了關鍵字strictfp來聲明某個類、接口或者方法時,那麼在這個關鍵字所聲明的範圍内所有浮點運算都是精确的,符合IEEE-754規範

的。例如一個類被聲明為strictfp,那麼該類中所有的方法都是strictfp的。

2)抽象類和接口有什麼差別?(瞬聯)

1.abstract class 在 Java 語言中表示的是一種繼承關系,一個類隻能使用一次繼承關系。但是,一個類卻可以實作多個interface。

2.在abstract class 中可以有自己的資料成員,也可以有非abstarct的成員方法,而在interface中,隻能夠有靜态的不能被修改的資料成員(也就是必須是static final的,不過在 interface中一般不定義資料成員),所有的成員方法都是abstract的。

3.abstract class和interface所反映出的設計理念不同。其實abstract class表示的是"is-a"關系,interface表示的是"like-a"關系。

4.實作抽象類和接口的類必須實作其中的所有方法。抽象類中可以有非抽象方法。接口中則不能有實作方法。

5.接口中定義的變量預設是public static final 型,且必須給其初值,是以實作類中不能重新定義,也不能改變其值。

6.抽象類中的變量預設是 friendly 型,其值可以在子類中重新定義,也可以重新指派。

7.接口中的方法預設都是 public,abstract 類型的。

3)能說一下java的反射(reflection)機制嗎?(瞬聯)

開放性和原因連接配接(causally-connected)是反射系統的兩大基本要素

4)在java中怎樣實作多線程?(瞬聯)

extends Thread

implement Runnable

方法一:繼承 Thread 類,覆寫方法 run(),我們在建立的 Thread 類的子類中重寫 run() ,加入線程所要執行的代碼即可。下面是一個例子:

  public class MyThread extends Thread

  {

   int count= 1, number;

   public MyThread(int num)

   {

    number = num;

    System.out.println

    ("建立線程 " + number);

   }

   public void run() {

    while(true) {

     System.out.println

      ("線程 " + number + ":計數 " + count);

     if(++count== 6) return;

    }

  }

  public static void main(String args[])

  {

   for(int i = 0;i 〈 5; i++) new MyThread(i+1).start();

  }

 }

  

  這種方法簡單明了,符合大家的習慣,但是,它也有一個很大的缺點,那就是如果我們的類已經從一個類繼承(如小程式必須繼承自 Applet 類),則無法再繼承 Thread 類,這時如果我們又不想建立一個新的類,應該怎麼辦呢?

  我們不妨來探索一種新的方法:我們不建立Thread類的子類,而是直接使用它,那麼我們隻能将我們的方法作為參數傳遞給 Thread 類的執行個體,有點類似回調函數。但是 Java 沒有指針,我們隻能傳遞一個包含這個方法的類的執行個體。

  那麼如何限制這個類必須包含這一方法呢?當然是使用接口!(雖然抽象類也可滿足,但是需要繼承,而我們之是以要采用這種新方法,不就是為了避免繼承帶來的限制嗎?)

  Java 提供了接口 java.lang.Runnable 來支援這種方法。

  方法二:實作 Runnable 接口

  Runnable接口隻有一個方法run(),我們聲明自己的類實作Runnable接口并提供這一方法,将我們的線程代碼寫入其中,就完成了這一部分的任務。但是Runnable接口并沒有任何對線程的支援,我們還必須建立Thread類的執行個體,這一點通過Thread類的構造函數 public Thread(Runnable target);來實作。下面是一個例子:

  public class MyThread implements Runnable

  {

   int count= 1, number;

   public MyThread(int num)

   {

    number = num;

    System.out.println("建立線程 " + number);

   }

   public void run()

   {

    while(true)

    {

     System.out.println

     ("線程 " + number + ":計數 " + count);

     if(++count== 6) return;

    }

   }

   public static void main(String args[])

   {

    for(int i = 0; i 〈 5;i++) new Thread(new MyThread(i+1)).start();

   }

  }

  

  嚴格地說,建立Thread子類的執行個體也是可行的,但是必須注意的是,該子類必須沒有覆寫 Thread 類的run 方法,否則該線程執行的将是子類的 run 方法,而不是我們用以實作Runnable 接口的類的 run 方法,對此大家不妨試驗一下。

  使用 Runnable 接口來實作多線程使得我們能夠在一個類中包容所有的代碼,有利于封裝,它的缺點在于,我們隻能使用一套代碼,若想建立多個線程并使各個線程執行不同的代碼,則仍必須額外建立類,如果這樣的話,在大多數情況下也許還不如直接用多個類分别繼承 Thread 來得緊湊。

  綜上所述,兩種方法各有千秋,大家可以靈活運用。

  下面讓我們一起來研究一下多線程使用中的一些問題。

  三、線程的四種狀态

  1. 新狀态:線程已被建立但尚未執行(start() 尚未被調用)。

  2. 可執行狀态:線程可以執行,雖然不一定正在執行。CPU 時間随時可能被配置設定給該線程,進而使得它執行。

  3. 死亡狀态:正常情況下 run() 傳回使得線程死亡。調用 stop()或 destroy() 亦有同樣效果,但是不被推薦,前者會産生異常,後者是強制終止,不會釋放鎖。

  4. 阻塞狀态:線程不會被配置設定 CPU 時間,無法執行。

  四、線程的優先級

  線程的優先級代表該線程的重要程度,當有多個線程同時處于可執行狀态并等待獲得 CPU 時間時,線程排程系統根據各個線程的優先級來決定給誰配置設定 CPU 時間,優先級高的線程有更大的機會獲得 CPU 時間,優先級低的線程也不是沒有機會,隻是機會要小一些罷了。

  你可以調用 Thread 類的方法 getPriority() 和 setPriority()來存取線程的優先級,線程的優先級界于1(MIN_PRIORITY)和10(MAX_PRIORITY)之間,預設是5(NORM_PRIORITY)。

5)你用過哪種設計模式?(瞬聯,IBM,aspenTech)

設計:design

模式:pattern

架構:framework

建立模式,結構模式和行為模式

GoF設計模式

A.建立模式

設計模式之Factory(工廠模式)

使用工廠模式就象使用new一樣頻繁.2002/10/9更新

設計模式之Prototype(原型模式)

用原型執行個體指定建立對象的種類,并且通過拷貝這些原型建立新的對象。

設計模式之Builder

汽車由車輪 方向盤 發動機很多部件組成,同時,将這些部件組裝成汽車也是一件複雜的工作,Builder模式就是将這兩種情況分開進行。

設計模式之Singleton(單态模式)

保證一個類隻有一個執行個體,并提供一個通路它的全局通路點 2002/10/9更新

B.結構模式

設計模式之Facade

可擴充的使用JDBC針對不同的資料庫程式設計,Facade提供了一種靈活的實作.

設計模式之Proxy

以Jive為例,剖析代理模式在使用者級别授權機制上的應用

設計模式之Adapter

使用類再生的兩個方式:組合(new)和繼承(extends),這個已經在"thinking in java"中提到過.

設計模式之Composite

就是将類用樹形結構組合成一個機關.你向别人介紹你是某機關,你是機關中的一個元素,别人和你做買賣,相當于和機關做買賣。文章中還對Jive再進行了剖析。

設計模式之Decorator

Decorator是個油漆工,給你的東東的外表刷上美麗的顔色.

設計模式之Bridge

将"牛郎織女"分開(本應在一起,分開他們,形成兩個接口),在他們之間搭建一個橋(動态的結合)

設計模式之Flyweight

提供Java運作性能,降低小而大量重複的類的開銷.

C.行為模式

設計模式之Template

實際上向你介紹了為什麼要使用Java 抽象類,該模式原理簡單,使用很普遍.

設計模式之Memento

很簡單一個模式,就是在記憶體中保留原來資料的拷貝.

設計模式之Observer

介紹如何使用Java API提供的現成Observer

設計模式之Chain of Responsibility

各司其職的類串成一串,好象擊鼓傳花,當然如果自己能完成,就不要推委給下一個.

設計模式之Command

什麼是将行為封裝,Command是最好的說明.

設計模式之State

狀态是程式設計中經常碰到的執行個體,将狀态對象化,設立狀态變換器,便可在狀态中輕松切換.

設計模式之Strategy

不同算法各自封裝,使用者端可随意挑選需要的算法.

設計模式之Mediator

Mediator很象十字路口的紅綠燈,每個車輛隻需和紅綠燈互動就可以.

設計模式之Interpreter

主要用來對語言的分析,應用機會不多.

設計模式之Visitor

通路者在進行通路時,完成一系列實質性操作,而且還可以擴充.

設計模式之Iterator

這個模式已經被整合入Java的Collection.在大多數場合下無需自己制造一個Iterator,隻要将對象裝入Collection中,直接使用Iterator進行對象周遊。

6)請說一下MVC架構(瞬聯,IBM,aspenTech)

Model:模型層

View:視圖層   

Controller:控制層

MVC (Modal View Controler)本來是存在于Desktop程式中的,M是指資料模型,V是指使用者界面,C則是控制器。使用MVC的目的是将M和V的實作代碼分離,進而使同一個程式可以使用不同的表現形式。比如一批統計資料你可以分别用柱狀圖、餅圖來表示。C存在的目的則是確定M和V的同步,一旦M改變,V應該同步更新。 

模型-視圖-控制器(MVC)是Xerox PARC在八十年代為程式設計語言Smalltalk-80發明的一種軟體設計模式,至今已被廣泛使用。最近幾年被推薦為Sun公司J2EE平台的設計模式,并且受到越來越多的使用ColdFusion 和 PHP 的開發者的歡迎。模型-視圖-控制器模式是一個有用的工具箱,它有很多好處,但也有一些缺點。 

MVC如何工作 

MVC是一個設計模式,它強制性的使應用程式的輸入、處理和輸出分開。使用MVC應用程式被分成三個核心部件:模型、視圖、控制器。它們各自處理自己的任務。 

視圖 

視圖是使用者看到并與之互動的界面。對老式的Web應用程式來說,視圖就是由HTML元素組成的界面,在新式的Web應用程式中,HTML依舊在視圖中扮演着重要的角色,但一些新的技術已層出不窮,它們包括Macromedia Flash和象XHTML,XML/XSL,WML等一些辨別語言和Web services. 

如何處理應用程式的界面變得越來越有挑戰性。MVC一個大的好處是它能為你的應用程式處理很多不同的視圖。在視圖中其實沒有真正的處理發生,不管這些資料是聯機存儲的還是一個雇員清單,作為視圖來講,它隻是作為一種輸出資料并允許使用者操縱的方式。 

模型 

模型表示企業資料和業務規則。在MVC的三個部件中,模型擁有最多的處理任務。例如它可能用象EJBs和ColdFusion Components這樣的構件對象來處理資料庫。被模型傳回的資料是中立的,就是說模型與資料格式無關,這樣一個模型能為多個視圖提供資料。由于應用于模型的代碼隻需寫一次就可以被多個視圖重用,是以減少了代碼的重複性。 

控制器 

控制器接受使用者的輸入并調用模型和視圖去完成使用者的需求。是以當單擊Web頁面中的超連結和發送HTML表單時,控制器本身不輸出任何東西和做任何處理。它隻是接收請求并決定調用哪個模型構件去處理請求,然後用确定用哪個視圖來顯示模型處理傳回的資料。 

現在我們總結MVC的處理過程,首先控制器接收使用者的請求,并決定應該調用哪個模型來進行處理,然後模型用業務邏輯來處理使用者的請求并傳回資料,最後控制器用相應的視圖格式化模型傳回的資料,并通過表示層呈現給使用者。 

為什麼要使用 MVC 

大部分Web應用程式都是用像ASP,PHP,或者CFML這樣的過程化語言來建立的。它們将像資料庫查詢語句這樣的資料層代碼和像HTML這樣的表示層代碼混在一起。經驗比較豐富的開發者會将資料從表示層分離開來,但這通常不是很容易做到的,它需要精心的計劃和不斷的嘗試。MVC從根本上強制性的将它們分開。盡管構造MVC應用程式需要一些額外的工作,但是它給我們帶來的好處是無庸質疑的。 

首先,最重要的一點是多個視圖能共享一個模型,正如我所提及的,現在需要用越來越多的方式來通路你的應用程式。對此,其中一個解決之道是使用MVC,無論你的使用者想要Flash界面或是 WAP 界面;用一個模型就能處理它們。由于你已經将資料和業務規則從表示層分開,是以你可以最大化的重用你的代碼了。 

由于模型傳回的資料沒有進行格式化,是以同樣的構件能被不同界面使用。例如,很多資料可能用HTML來表示,但是它們也有可能要用Macromedia Flash和WAP來表示。模型也有狀态管理和資料持久性處理的功能,例如,基于會話的購物車和電子商務過程也能被Flash網站或者無線聯網的應用程式所重用。 

因為模型是自包含的,并且與控制器和視圖相分離,是以很容易改變你的應用程式的資料層和業務規則。如果你想把你的資料庫從MySQL移植到Oracle,或者改變你的基于RDBMS資料源到LDAP,隻需改變你的模型即可。一旦你正确的實作了模型,不管你的資料來自資料庫或是LDAP伺服器,視圖将會正确的顯示它們。由于運用MVC的應用程式的三個部件是互相對立,改變其中一個不會影響其它兩個,是以依據這種設計思想你能構造良好的松偶合的構件。 

對我來說,控制器的也提供了一個好處,就是可以使用控制器來聯接不同的模型和視圖去完成使用者的需求,這樣控制器可以為構造應用程式提供強有力的手段。給定一些可重用的模型和視圖,控制器可以根據使用者的需求選擇模型進行處理,然後選擇視圖将處理結果顯示給使用者。 

MVC的缺點 

MVC的缺點是由于它沒有明确的定義,是以完全了解MVC并不是很容易。使用MVC需要精心的計劃,由于它的内部原理比較複雜,是以需要花費一些時間去思考。 

你将不得不花費相當可觀的時間去考慮如何将MVC運用到你的應用程式,同時由于模型和視圖要嚴格的分離,這樣也給調試應用程式到來了一定的困難。每個構件在使用之前都需要經過徹底的測試。一旦你的構件經過了測試,你就可以毫無顧忌的重用它們了。 

根據我個人經驗,由于我們将一個應用程式分成了三個部件,是以使用MVC同時也意味着你将要管理比以前更多的檔案,這一點是顯而易見的。這樣好像我們的工作量增加了,但是請記住這比起它所能帶給我們的好處是不值一提。 

MVC并不适合小型甚至中等規模的應用程式,花費大量時間将MVC應用到規模并不是很大的應用程式通常會得不償失。 

MVC是一條建立軟體的好途徑 

MVC設計模式是一個很好建立軟體的途徑,它所提倡的一些原則,像内容和顯示互相分離可能比較好了解。但是如果你要隔離模型、視圖和控制器的構件,你可能需要重新思考你的應用程式,尤其是應用程式的構架方面。如果你肯接受MVC,并且有能力應付它所帶來的額外的工作和複雜性,MVC将會使你的軟體在健壯性,代碼重用和結構方面上一個新的台階。

7)如果類a繼承類b,實作接口c,而類b和接口c中定義了同名變量,請問會出現什麼問題?(瞬聯)

interface      A

{

       int x = 0;

}

class B

{

       int x =1;

}

class C extends B implements A

{

       public void pX()

{

        System.out.println(x);

     }

       public static void main(String[] args) {

          new C().pX();

       }

}

答案:錯誤。在編譯時會發生錯誤(錯誤描述不同的JVM有不同的資訊,意思就是未明确的x調用,兩個x都比對(就象在同時import java.util和java.sql兩個包時直接聲明Date一樣)。對于父類的變量,可以用super.x來明确(輸出的是1),而接口的屬性預設隐含為 public static final.是以可以通過A.x來明确(輸出的是0)。

下面的代碼運作時會不會報錯

interface Playable

{

        void play();

}

interface Bounceable

{

        void play();

}

interface Rollable extends Playable, Bounceable

{

        Ball ball = new Ball("PingPang");

}

class Ball implements Rollable

{

        private String name;

        public String getName()

{

            return name;

        }

        public Ball(String name)

{

            this.name = name;        

        }

       public void play()

{

            ball = new Ball("Football");

            System.out.println(ball.getName());

        }

}

答案: 錯。"interface Rollable extends Playable, Bounceable"沒有問題。interface可繼承多個interfaces,是以這裡沒錯。問題出在interface Rollable裡的"Ball ball = new Ball("PingPang");"。任何在interface裡聲明的interface variable (接口變量,也可稱成員變量),預設為public static final。也就是說"Ball ball = new Ball("PingPang");"實際上是"public static final Ball ball = new Ball("PingPang");"。在Ball類的Play()方法中,"ball = new Ball("Football");"改變了ball的reference,而這裡的ball來自Rollable interface,Rollable interface裡的ball是public static final的,final的object是不能被改變reference的。是以編譯器将在"ball = new Ball("Football");"這裡顯示有錯。

8)請說一下java中為什麼要引入内部類?還有匿名内部類?(瞬聯,IBM)

9)請說一下final,finally和finalize的差別?(瞬聯)

final 用于聲明屬性,方法和類,分别表示屬性不可變,方法不可覆寫,類不可繼承。

finally是異常處理語句結構的一部分,表示總是執行。

finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆寫此方法提供垃圾收集時的其他資源回收,例如關閉檔案等。

10)請說一下HTTP請求的基本過程(IBM)

11)java中存在記憶體洩漏問題嗎?請舉例說明?(IBM)

會  

int i,i2;     return (i-i2);      //when i為足夠大的正數,i2為足夠大的負數。結果會造成溢位,導緻錯誤。

12)請說一下java中的記憶體回收機制所采用的算法(IBM,瞬聯)

雖然垃圾回收關心着大部分的問題,包括記憶體管理,使得程式員的任務顯得更加輕松,但是程式員還是可能犯些錯誤導緻記憶體洩漏問題。GC(垃圾回收)通過遞歸對所有從“根”對象(堆棧中的對象,靜态資料成員,JNI句柄等等)繼承下來的引用進行工作,然後标記所有可以通路的活動着的對象。而這些對象變成了程式唯一能夠操縱的對象,其他的對象都被釋放了。因為GC使得程式不能夠通路那些被釋放的對象,是以這樣做是安全的。

13)請說一下System.gc()函數的作用。什麼時候可以調用垃圾回收器?(瞬聯)

垃圾回收函數,手動調用的.

當一個對象停止被活動聲明所引用,它就變成了垃圾(garbage)可以被回收重新使用

14)你做過的項目中采用了什麼安全認證機制?(IBM)

15)Math.round()什麼作用?

     Math.Round(3.44, 1) = 3.4

       Math.Round(3.45, 1) = 3.4

       Math.Round(3.46, 1) = 3.5

       -----------------------------------------------

       Math.Round(3.54, 1) = 3.5

       Math.Round(3.55, 1) = 3.6

       Math.Round(3.56, 1) = 3.6

       -----------------------------------------------

       Math.Round(3.64, 1) = 3.6

       Math.Round(3.65, 1) = 3.6

       Math.Round(3.66, 1) = 3.7

       -----------------------------------------------

       Math.Round(3.74, 1) = 3.7

       Math.Round(3.75, 1) = 3.8

       Math.Round(3.76, 1) = 3.8

這種舍入方法叫做銀行家舍入(Banker'sRound),這就是已經規定下來的标準、Round的标準、世界的标準。

Round <> 四舍五入

16、設計4個線程,其中兩個線程每次對j增加1,另外兩個線程對j每次減少1。寫出程式。

以下程式使用内部類實作線程,對j增減的時候沒有考慮順序問題。

package java_example150;

public class TestThread3{

 private int j;

 public static void main(String[] args){

  TestThread3 t = new TestThread3();

     Inc inc = t.new Inc();

     Dec dec = t.new Dec();

     for(int i=0;i<2;i++){

      Thread ts = new Thread(inc);

      ts.start();

      ts= new Thread(dec);

      ts.start();

     }

 }

 private synchronized void inc(){

     j++;

     System.out.println(Thread.currentThread().getName()+"-inc:"+j);

 }

 private synchronized void dec(){

     j--;

     System.out.println(Thread.currentThread().getName()+"-dec:"+j);

 }

 class Inc implements Runnable{

    public void run(){

     for(int i=0;i<10;i++){

      inc();

     }

    }

 }

 class Dec implements Runnable{

  public void run(){

   for(int i=0;i<10;i++){

    dec();

   }

     }

 }

}

17.CORBA是什麼?用途是什麼? 

答:CORBA 标準是公共對象請求代理結構(Common Object Request Broker Architecture),由對象管理組織 (Object Management Group,縮寫為 OMG)标準化。它的組成是接口定義語言(IDL), 語言綁定(binding:也譯為聯編)和允許應用程式間互操作的協定。 其目的為:

1. 用不同的程式設計語言書寫 

2. 在不同的程序中運作 

3. 為不同的作業系統開發

18.JAVA代碼查錯

1.

abstract class Name

{

    private String name;

    public abstract boolean isStupidName(String name) {}

}

答案: 錯。abstract method必須以分号結尾,且不帶花括号。

2.

public class Something

{

    void doSomething ()

   {

        private String s = "";

        int l = s.length();

    }

}

答案: 錯。局部變量前不能放置任何通路修飾符 (private,public,和protected)。final可以用來修飾局部變量

(final如同abstract和strictfp,都是非通路修飾符,strictfp隻能修飾class和method而非variable)。

3.

abstract class Something

{

    private abstract String doSomething ();

}

答案: 錯。abstract的methods不能以private修飾。abstract的methods就是讓子類implement(實作)具體細節的,怎麼可以用private把abstractmethod封鎖起來呢? (同理,abstract method前不能加final)。

4.

public class Something

{

    public int addOne(final int x)

    {

        return ++x;

    }

}

答案: 錯。int x被修飾成final,意味着x不能在addOne method中被修改。

5.

public class Something

{

    public static void main(String[] args)

    {

        Other o = new Other();

        new Something().addOne(o);

    }

    public void addOne(final Other o)

    {

        o.i++;

    }

}

class Other

{

    public int i;

}

答案: 正确。在addOne method中,參數o被修飾成final。如果在addOne method裡我們修改了o的reference

(比如: o = new Other();),那麼如同上例這題也是錯的。但這裡修改的是o的member vairable

(成員變量),而o的reference并沒有改變。

6.

class Something

{

     int i;

     public void doSomething()

     {

         System.out.println("i = " + i);

     }

}

答案: 正确。輸出的是"i = 0"。int i屬於instant variable (執行個體變量,或叫成員變量)。instant variable有default value。int的default value是0。

7.

class Something

{

     final int i;

     public void doSomething()

     {

         System.out.println("i = " + i);

     }

}

答案: 錯。final int i 是個final的 instant variable (執行個體變量,或叫成員變量)。final的instant variable沒有default value,必須在constructor (構造器)結束之前被賦予一個明确的值。可以修改為"final int i = 0;"。

8.

public class Something

{

      public static void main(String[] args)

     {

         Something s = new Something();

         System.out.println("s.doSomething() returns " + doSomething());

     }

     public String doSomething()

    {

         return "Do something ...";

     }

}

答案: 錯。看上去在main裡call doSomething沒有什麼問題,畢竟兩個methods都在同一個class裡。但仔細看,main是static的。static method不能直接call non-static methods。可改成"System.out.println("s.doSomething() returns " + s.doSomething());"。同理,static method不能通路non-static instant variable。