q1:給出一些使用Java的理由。
a1:java是一個有趣的程式設計語言,讓我找出一些理由來: 內建的多線程機制、通訊端、記憶體管理(自動記憶體回收) 物件導向 跨平台 通過對標準API的擴充來支援基於web的應用程式(applet、servlet、jsp),分布式應用程式(socket、RMI、EJB)和網路通訊協定(HTTP、JRMP等)。
q2:java平台和別的軟體平台有什麼主要區別。
a2:java平台是純粹的軟體平台,運行在別的基於硬體的平台之上(如UNIX、NT等)。
java平台由兩部分組成: java虛擬機器(JVM):是硬體平台上的一個軟體,位元組碼(class檔案)是JVM的機器語言。 java Application Programing Interface(API)——系列用Java語言編寫的class檔案,它們運行在JVM上。
q3:C++和Java有哪些區別。
a3:雖然Java和C++都使用相近的文法而且都是物件導向的程式設計語言,但是: Java不支援指標。指標天生較為教滑和令人討厭。 Java不支援多重繼承,因為這帶來的麻煩比它解決的要多。作為替代,Java支援多介面繼承,運行一個類繼承(實現)多個來自不同介面的方法簽名。多介面繼承運行子類對象的行為具備多態性。 Java不支援解構函式,但是添加了finalize()方法。記憶體回收行程在回收對象前會調用其finalize()方法,但是我們並不知道對象何時被回收。我們不應該使用finalize來釋放資源,例如檔案處理、socket、資料庫連接,因為這些資源都很有限,我們並不知道finalize()方法何時被調用。 Java沒有結構體或者聯合體,因為傳統的資料結構被設計為一個物件導向的架構(Java集合架構)。
q4:Java packages有什麼作用。
a4:多個包下可以有同名的類,因此包可以協助我們解決命名衝突的問題。另外,它可以很好地組織檔案。例如 java.io 包與I/O相關而java.net包與網路相關,等等。如果我們將所有的.java檔案放在單個包中,隨著項目的增大,將會很難管理這些檔案。
我們可以通過package來聲明類所在的包。package關鍵字應該是源碼中出現的第一個關鍵字,隨後是import語句。預設情況下,java.lang包會被隱式地引入,而其它包都必須顯式地引入。
package com.xyz.client ; import java.io.File; import java.net.URL;
q5:解釋Java類載入器(class loader)?如果你有一個類在一個包裡,你需要做什麼才能運行它?解釋動態類載入?
a5:類載入器是分等級的。當已經運行在JVM中類引用了一個類的名字時,這個類才會被載入到JVM中。那麼,第一個類是如何被載入的呢。JVM要載入的第一個類是聲明了main()方法並被啟動並執行類。接下來所有被裝載的類都是由它引發的——它已經在JVM中並處於運行狀態。
一個類裝載器建立一個命名空間。所有JVM至少有一個類裝載器,被稱為原始類載入器或者引導類載入器,它是由C或者C++實現的。除此之外,Java允許用java語言編寫的類載入器來載入class檔案。通常JVM提供兩個這樣的非原始類載入器: 引導類載入器(Bootstrap)——載入JDK內部的class檔案(java.*包),典型地,它載入rt.jar和i18n.jar 擴充類載入器(Extensions)——載入JDK擴充路徑下的jar包, java.ext.dirs系統變數指定的路徑,通常是JRE的lib/ext路徑 系統類別載入器(System)——從系統classpath載入class檔案,系統classpath由 java.class.path系統變數決定,它通過CLASSPATH環境變數或者命令列的–classpath / –cp參數指定
類載入器是分層級的,而且採用委託模型。類裝載器會先請求其父級類載入器載入類檔案,如果父級載入器未能載入,再自己載入。一旦父級載入器已經載入該類,子載入器不會重複載入。子載入器載入的類可訪問父載入器載入的類,但是反過來不成立。
Q:在某個package下擁有main()方法的class,你需要做什麼才能運行它。
舉例來說:你有一個類名為“Pet”在工程檔案“c:\myProject”並且包名為“com.xyz.client”,你能用下列方式編譯和運行它嗎。
package com.xyz.client; public class Pet { public static void main(String[] args) { System.out.println("I am found in the classpath"); } }
To run --》 c:\myProject> java com.xyz.client.Pet
答案是不行。你將會得到這樣的異常:“Exception in thread "main" java.lang.-NoClassDefFoundError: com/xyz/client/Pet”.
你需要設定classpath 設定作業系統的“CLASSPATH”環境變數,包含工程檔案“c:\myProject” 設定作業系統的“CLASSPATH”環境變數,包含工程檔案“c:\myProject\client.jar”,這個jar包應含有Pet.class類檔案。 運行命令列提供-cp或者-classpath環境變數:
c:\>java -cp c:/myProject com.xyz.client.Pet OR c:\>java -classpath c:/myProject/client.jar com.xyz.client.Pet
Q:解釋靜態vs動態類載入。
靜態類載入
|
動態類載入
|
類的靜態載入伴隨著Java的new操作符
class MyClass { public static void main(String args[]) { Car c = new Car(); } }
|
動態載入是在運行期調用類裝載功能的一種編程技術。 //static method which returns a Class Class.forName (String className );
上面的靜態方法返回一個和類名關聯的Class執行個體。字串“className”可以在運行期被動態地提供。不像靜態載入,動態載入決定載入Car類檔案或者Jeep類檔案,是基於屬性檔案或者其它運行期條件的。一旦類被載入,就可以通過下列方式來建立類的一個執行個體(就像用new操作符調用一個無參構造器那樣。)
class.newInstance () ; //A non-static method, which creates an instance of a //class (i.e. creates an object). Jeep myJeep = null ; //myClassName should be read from a .properties file or a Constants class. // stay away from hard coding values in your program. String myClassName = "au.com.Jeep" ; Class vehicleClass = Class.forName(myClassName) ; myJeep = (Jeep) vehicleClass.newInstance(); myJeep.setFuelCapacity(50); |
NoClassDefFoundException異常將被拋出,如果用new操作符使用一個類,但是在運行期系統並未找到這個被引用的類。
|
ClassNotFoundException將會被拋出,如果程式試圖使用下列方式之一,通過字串類名載入一個類,而這個類未被定義的話。
The forName(..) method in class - Class. The findSystemClass(..) method in class - ClassLoader. The loadClass(..) method in class - ClassLoader.
|
Q:靜態初始化和靜態塊是什麼。
A:當一個類被載入的時候,其靜態塊就會被執行,這會先於構造器的執行。正如其名,它用於初始化靜態成員。
public class StaticInitializer { public static final int A = 5; public static final int B; //note that it is not Æ public static final int B = null ; //note that since B is final , it can be initialized only once. //Static initializer block, which is executed only once when the class is loaded. static { if(A == 5) B = 10; else B = 5; } public StaticInitializer(){} //constructor is called only after static initializer block }
下列代碼將會輸出:A=5, B=10
public class Test { System.out.println("A =" + StaticInitializer.A + ", B =" + StaticInitializer.B); }