国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Java入門記(一):折騰HelloWorld

2019-11-14 23:03:32
字體:
供稿:網(wǎng)友
java入門記(一):折騰HelloWorld

  HelloWorld,學(xué)習(xí)每門語言的第一步。有人戲稱,這些年的編程生涯就是學(xué)習(xí)各種語言的HelloWorld,不知是自謙還是自嘲。目前所在的公司使用Java作為主要開發(fā)語言,我進行語言轉(zhuǎn)換也大半年了,這HelloWorld便是語言轉(zhuǎn)換的第一關(guān)。好在本科的時候?qū)W過那么一點,而且在此之前進行了較長時間的C/C++開發(fā),其間有不少的相似之處。這里略去JDK的安裝和環(huán)境配置(JDK為1.6.0.45),直接從代碼入手。

  首先看一個最簡單的Java下的HelloWorld:

public class HelloWorld {  public static void main(String[]agrs)    {      System.out.

  一般來說,初學(xué)者寫HelloWorld到這里,編譯完運行一下看到結(jié)果就可以結(jié)束了。下面對這個小程序進行更多的探索,進一步了解和學(xué)習(xí)Java編程中的特性。

1.
源碼文件的編碼

  最初為了簡單起見,我是在Win7中用記事本編寫并保存代碼為HelloWorld.java,然后用命令行直接javac編譯。出于在Windows下寫linux程序的習(xí)慣,我在記事本保存時將代碼保存為UTF-8編碼的HelloWorld.java文件。編譯時提示:

  在仔細檢查源代碼確定沒有任何拼寫錯誤后,嘗試將編碼改回Windows默認(rèn)的ANSI,成功生成了HelloWorld.class并能夠正確運行,看來是編碼不一致惹得禍。接下來,抱著嘗試的心態(tài),使用Unicode和Unicode Big Endian保存源碼,發(fā)現(xiàn)也會報錯,只是提示不同,編譯器提示有非法字符。這個問題如果在Eclipse中用默認(rèn)方式保存文件,則不會出現(xiàn)。

  有趣的是,如果使用Java的I/O方法生成文本文件,應(yīng)該如何確定文件的編碼,也是一個常見的問題。如果僅僅是涉及Windows/Linux兩個平臺之間的編碼差異,而不包括中文編碼,前者使用/r/n,而后者使用/n/r或/n即可。對于漢字編碼,需要在使用到的I/O方法中指定編碼,這里不再做一步的詳述。

2.為什么沒有import語句?

  還記得經(jīng)典的K&R中經(jīng)典的HelloWorld么?即使極盡精簡,C中仍然避免不了使用#include <stdio.h>來引入頭文件,才能使用printf函數(shù)。

  而Java和C/C++不一樣,這個簡單的HelloWorld不需要類似include的import,也不需要使用命名空間,看似更簡單了些。實際上,這是因為Java給每個Java文件都默認(rèn)導(dǎo)入了java.lang這個包,從而省去了import java.lang;這個語句罷了。這樣,下面進行屏幕輸出直接使用System.out.println()即可。

  java.lang中包括的都是常用的類和方法,具體內(nèi)容讀者有興趣可以自行查閱。上文提到j(luò)ava.import是“默認(rèn)導(dǎo)入”,有沒有什么辦法禁止其導(dǎo)入?我搜索了下,目前還沒有查到相關(guān)的資料,如果哪位讀者了解,希望能告訴我。(這可能涉及到類加載器的問題,暫未進行研究)

  如果你執(zhí)意在這段簡單的代碼中使用與import對應(yīng)的package,可以參考本文第六節(jié)。

3.文件名為什么要與類名一致?類名與修飾符問題

  在實踐中可以看出,編譯結(jié)果是HelloWorld.class,但是運行的命令卻是java HelloWorld。如果這個文件還有更多的類,可以看到這些類在編譯時都生成了*.class文件。對于“類名和文件名一致”這個疑問提的并不合理,顯然代碼編寫時,一個文件中可以有很多個類。這涉及到了Java的特性(來自《Java編程思想(第四版中文版)》):

每個編譯單元(文件)只能最多有一個public類;如果有,其名稱必須與含有這個編譯單元的文件名相匹配,包括大小寫。

  如果不遵守這個要求,寫出類似下面的代碼

//ERROR IN CODEpublic class HelloWorld {  public static void main(String[]agrs)    {      System.out.println("HelloWorld!");    }}public class HelloWorld2 {  public static void main(String[]agrs)    {      System.out.println("HelloWorld, me too!");    }}

  那么編譯器會提示這一點

  如果把HelloWorld2類的public去掉,將使其變成包訪問權(quán)限,程序可以正常運行,此時只執(zhí)行HelloWorld.main(),并不會發(fā)生沖突。

  實際上,如果這個文件只有一個HelloWorld類,或者有兩個類,只要這個包括main()的類名與文件名一致,類名前不加public也是可以正常運行的,且調(diào)用的是與文件名一致的類的main()方法。但個人認(rèn)為這不是良好的編程實踐,如下:

class HelloWorld {  public static void main(String[]agrs)    {      System.out.println("HelloWorld!");    }}class HelloWorld2 {  public static void main(String[]agrs)    {      System.out.println("HelloWorld, me too!");    }}

  編譯時將生成HelloWorld.class和HelloWorld2.class,分別運行時,結(jié)果為兩個類各自的main()方法。

4.main()函數(shù)的參數(shù)表和修飾符

  在C中,對于main()的修飾符和參數(shù)表有著很多細節(jié)要注意(可以參考五花八門的main())。對于Java,這里對main()的寫法也進行簡單的探究。

  先來看參數(shù)表String args[]。雖說編譯器要求必須是這種形式,但如果不用標(biāo)準(zhǔn)形式而用其他形式如int x、String s作為參數(shù)表,編譯是可以通過的,但是在執(zhí)行時則會拋出異常,無論是否提供了參數(shù):

  NoSuchMethodError表名,期望的是參數(shù)為String args[]的main()方法。雖然提供了同名方法,由于方法的重載機制,并不能代替期望的main(String args[])方法。

  接下來看修飾符public。在第3條已經(jīng)提到了public對于類名的修飾有所說明,而對于main()這個與文件同名的類的成員方法,為了能被調(diào)用,只能用public修飾。不使用修飾符(包訪問權(quán)限)、使用private或protected都會提示:

  對于修飾符static,表明這個方法是在存儲在靜態(tài)存儲區(qū)的,不需要實例化對象就可以調(diào)用。去掉static后,可以編譯通過,運行時提示

為了進一步驗證這一點,可以編寫構(gòu)造方法來驗證。(構(gòu)造方法是在類的對象在實例化時會被調(diào)用的方法)

public class HelloWorld {    HelloWrold    {        System.out.println("Constructor");    }    public static void main(String[]agrs)    {      System.out.println("HelloWorld!");    }}

  編譯運行時,可以看到構(gòu)造方法并沒有運行。

  對于修飾符void,也是必須的。改成int等并加上對應(yīng)的return語句同樣會提示“NoSuchMethodError: main”。在《Java虛擬機規(guī)范(JavaSE7)》(周志明等譯)中介紹到

Java虛擬機的啟動是通過引導(dǎo)類加載器(Bootstrap Class Loader §5.3.1)創(chuàng)建一個初始類(Initial Class)來完成,這個類是由虛擬機的具體實現(xiàn)指定。緊接著,Java虛擬機鏈接這個初始類,初始化并調(diào)用它的public void main(String[])方法。之后的整個執(zhí)行過程都是由對此方法的調(diào)用開始。

  可見,void返回值也是被要求的,其他形式是不允許的。

  經(jīng)過進一步的測試可知,args[0]是第一個參數(shù);而在C中,argv[0]是執(zhí)行的程序名。

5.既然main()方法是類方法……

  既然main()方法是類方法,那么在實例化這個類的對象時,自然可以再次調(diào)用這個方法。對HelloWorld源代碼加對應(yīng)的兩行,如下所示

public class HelloWorld {  public static void main(String[] args)    {        HelloWorld h = new HelloWorld();        System.out.println("HelloWorld!");        h.main(args);    }}

運行結(jié)果為

HelloWorld!

HelloWorld!

HelloWorld!

... ...HelloWorld!Exception in thread "main" java.lang.StackOverflowErrorat sun.nio.cs.ext.DoubleByteEncoder.encodeLoop(Unknown Source)at java.nio.charset.CharsetEncoder.encode(Unknown Source)at sun.nio.cs.StreamEncoder.implWrite(Unknown Source)at sun.nio.cs.StreamEncoder.write(Unknown Source)at java.io.OutputStreamWriter.write(Unknown Source)at java.io.BufferedWriter.flushBuffer(Unknown Source)at java.io.PrintStream.write(Unknown Source)at java.io.PrintStream.print(Unknown Source)at java.io.PrintStream.println(Unknown Source)at main.HelloWorld.main(HelloWorld.java:15)at main.HelloWorld.main(HelloWorld.java:16)at main.HelloWorld.main(HelloWorld.java:16)at main.HelloWorld.main(HelloWorld.java:16)... ...

  可見HelloWorld被玩壞了,這個無限遞歸創(chuàng)建對象的過程導(dǎo)致了內(nèi)存溢出。

6.試試package

  當(dāng)然,使用java更多的時候往往要處理多個文件。為了組織同一命名空間下的文件,需要使用包來進行。對應(yīng)于import,為了指定當(dāng)前文件在哪個包,需要加上package語句。隨便加上一個包名,最初的代碼變成了

import test;public class HelloWorld {  public static void main(String[]agrs)    {      System.out.println("HelloWorld!");    }}

編譯后,卻無法運行,如下圖所示

  其實,包名是隱含目錄結(jié)構(gòu)的。為了運行,需要把HelloWorld.class移入這個路徑的test文件夾,按照下面的方式運行才可以:

小結(jié)

  可見,對于一個小小的HelloWorld,還是有不少東西可以發(fā)掘,只是限于篇幅和本人水平,本文僅僅進行了簡要的介紹。以下是本文提出的可以在后續(xù)學(xué)習(xí)中繼續(xù)深入的主題,僅供參考:

1.I/O方法編碼方式的選擇

2.包和代碼組織

3.Java虛擬機(JVM)

相關(guān)閱讀

深入理解Java HelloWorld


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 晋州市| 穆棱市| 井冈山市| 射洪县| 增城市| 吉木乃县| 齐齐哈尔市| 平阳县| 吉安县| 阜阳市| 大关县| 和田市| 固始县| 木兰县| 德清县| 呈贡县| 桂东县| 汤原县| 西充县| 尚义县| 屏山县| 平陆县| 怀安县| 灵山县| 肇州县| 宜春市| 永新县| 宝山区| 搜索| 行唐县| 会泽县| 宁都县| 溧阳市| 高台县| 珠海市| 巴塘县| 浮梁县| 平南县| 获嘉县| 潼关县| 临洮县|