淺談為什麼一個java原始檔中只能有一個public類?
閒著沒事,在網上看到一個帖子在問為什麼一個java原始檔中只能有一個public類?
網上有人這麼回答:http://topic.csdn.net/t/20060528/22/4784755.html
、每個編譯單元(檔案)只能有一個public類。這麼做的意思是,每個編
譯單元只能有一個公開的介面,而這個介面就由其public類來表示。
我想這或是從軟體架構設計和安全性設計上得出的結論。或者說是java的設計者們從這方面的考慮。或許這真的是一個規範,但我沒有找到相關資料
不曉得到底有沒有這一說話。如果有請知道的同行給出資料來源?
實驗如下:
Test3.java原始檔:
class Test1
{
int i = 1;
}
class Test2
{
int i = 2;
public static void main(String[] args)
{
System.out.println("main method");
}
}
C:/javatest>javac Test3.java
C:/javatest>java Test2
main method
注:編譯不會出錯,注意是執行的Test2 因為沒有Test3.class檔案生成。如果執行Test3則報錯
找不到該類
C:/javatest>java Test3
Exception in thread "main" java.lang.NoClassDefFoundError: Test3
Caused by: java.lang.ClassNotFoundException: Test3
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
這個錯誤原因很簡單:JVM中的類載入器找不到Test3.class
同時這裡也說明了包含main()的類如果想執行則不一定要是public的。
《深入jvm第二版》中有這樣一句話:
java虛擬機器例項通過呼叫某個類的main()來執行一個Java程式,而這個main()必須是public
static void 並接收一個字串陣列作為引數,任何擁有這樣一個main()的類都可以作為java程
序的起點。
並沒有說擁有main()方法的類一定要是public類。
Test7.java原始檔:
class Test5
{
int i = 1;
}
public class Test6
{
int i = 2;
public static void main(String[] args)
{
System.out.println("main method");
}
}
如果執行Test7.java 報錯:
C:/javatest>javac Test7.java
Test7.java:8: 類 Test6 是公共的,應在名為 Test6.java 的檔案中宣告
public class Test6
^1 錯誤
這裡說明了檔名必須與public類的類名一致,(如果檔案中有public類)
這裡可以看出如果有多個public類,那麼檔名應該是哪個public類的呢?顯然一個java原始檔
只能有一個public類。
所以總結如下:一個Java原始檔中最多隻能有一個public類,當有一個public類時,原始檔名必
須與之一致,否則無法編譯,如果原始檔中沒有一個public類,則檔名與類中沒有一致性要求。
至於main()不是必須要放在public類中才能執行程式。
以上是通過實驗得出的結論,個人認為到這裡已經可以了,如果一定要追問到底,可能要問問java
平臺的設計者了。或許,人家會說:這是java的設計和jvm的內部體系結構設計造成,這是一個規
範,沒有為什麼。