1. 程式人生 > >課程作業02(關於java的幾點討論)

課程作業02(關於java的幾點討論)

區域 spa 不依賴 箭頭 精度問題 是什麽 sta 包裝 才有

討論一:

文件名必須與公有類名一致

類源文件名=公有類名+ .java 註意:如果一個類被聲明為public,則它本身所在的源文件名也必須與類名相同,連大小寫都不能錯!這並非說一個Java源文件中只能寫一個類,完全可以寫多個類,但其中只能有一個類是“公有(public)”的,並且Java要求源文件名也要與之一致。(接口結論同樣適用)。 置疑:一個Java類文件中真的只能有一個共有類嗎?
public class Test{ public static void main(String[] args){ } public class InnerClass{} }
經檢驗這個代碼無錯,可以得出結論:一個java源文件中可以寫多個類,但其中只能有一個類是“公有(public)”(不包含內類函數),且源文件名必須與公有類名一致,否則無法編譯。

討論二:

main方法

Java中的方法用於完成某個任務並返回結果信息,一個Java應用程序可以包含一個或多個方法Java應用程序(Java Application)從 main 方法開始執行 public static void main(String args[])main方法必須嚴格像上面那樣聲明,void表明main方法不返回任何結果,並且main()不是必須要放在public類中才能運行。 把main()方法的返回值由 void 改為 int ,程序能編譯通過嗎?能運行嗎? 技術分享

技術分享

無論是否加 return 0;都不可執行。

討論三:

什麽是靜態方法? 用static 修飾的方法稱為類方法或靜態方法。類方法是不依賴特定對象的方法,所以可以通過類名去引用該方法。無須創建對象即可使用的方法。 由於在加載類時,系統就為類中的方法分配了空間,所以在靜態方法中可以直接訪問本類的靜態變量和靜態方法,但在靜態方法中不能直接訪問實例字段和實例方法,也不能使用this關鍵字和super關鍵字。
class Circle{ static float PI=3.14f; int r; static float getArea(){ return PI*r*r;//編譯錯誤 }
思索:為什麽java規定程序入口點的main()方法靜態的?

在java中,main()方法是java應用程序的入口方法,也就是說,程序在運行的時候,第一個執行的方法就是main()方法,這個方法和其他的方法有很大的不同,比如方法的名字必須是main,方法必須是public static void類型的,方法必須是接受一個字符串數組的參數等。

因為main()方法是由Java虛擬機調用的,所以必須是public,虛擬機調用的main()方法的時候,不需要產生任何對象,所以main()方法聲明為static,且不需要返回值,所以必須聲明為void,最終格式如下所示:    public void main(String[] args)

技術分享 討論三: 變量的作用域 變量的作用域:每個變量都有一個“有效”的區域(稱為“作用域”),出了這個區域,變量將不再有效。 技術分享 技術分享

技術分享

技術分享 Java變量遵循“同名變量的屏蔽原則”,請課後閱讀相關資料弄清楚相關知識,然後自己編寫一些測試代碼,就象本示例一樣,有意識地在不同地方定義一些同名變量,看看輸出的到底是哪個值。 輸出的值為變量的有效區域的值。 討論四: 變量間類型轉換 自動類型轉換是安全的:
int intValue=100; long longValue=intValue;
強制類型轉換時,可能會引起信息的損失。
double doubleValue=1234567890; float floatValue=(float)doubleValue; System.out.println(floatValue); //1.23456794E9
除了使用C的強制類型轉換方式,還可以通過原始類型的包裝類完成類型轉換: 技術分享 適用場景: 同一個數據需要轉換為多種類型,並且這一數據需要比較長期的使用。多數情況下,推薦直接使用強制類型轉換的方式。 技術分享 實箭頭為無精度損失 虛箭頭為有精度損失
類型 長度及描述 範圍
char 16位,Unicode字符 \u000~\uffff或0~65535
byte 8位,有符號,字節 -128~127
short 16位,有符號,短整型 -32768~32767
int 32位,有符號,整型 -2147483648~2147483647
long 64位,有符號,長整型 -9.223E18~9.223E18
float 32位,浮點數,IEEE754格式 大約-3.4E+38~3.4E+38
double 64位,浮點數,IEEE754格式 大約-1.7E+308~1.7E+308

長度大向長度小賦值,會有精度損失

動手實驗:

運行此程序,你看到了什麽樣的輸出,意外嗎?

技術分享

技術分享

結論:使用double類型的數值進行計算, 其結果是不精確的。

為什麽double類型的數值進行運算得不到“數學上精確”的結果?這個涉及到二進制與十進制的轉換問題。

N進制可以理解為:數值×基數的冪,例如我們熟悉的十進制數123.4=1×102+2×10+3×(10的0次冪)+4×(10的-1次冪);其它進制的也是同理,例如二進制數11.01=1×2+1×(2的0次冪)+0+1×(2的-2次冪)=十進制的3.25。
double類型的數值占用64bit,即64個二進制數,除去最高位表示正負符號的位,在最低位上一定會與實際數據存在誤差(除非實際數據恰好是2的n次方)。

舉個例子來說,比如要用4bit來表示小數3.26,從高到低位依次對應2的1,0,-1,-2次冪,根據最上面的分析,應當在二進制數11.01(對應十進制的3.25)和11.10(對應十進制的3.5)之間選擇。
簡單來說就是我們給出的數值,在大多數情況下需要比64bit更多的位數才能準確表示出來(甚至是需要無窮多位),而double類型的數值只有64bit,後面舍去的位數一定會帶來誤差,無法得到“數學上精確”的結果。

技術分享

如何處理精度損失?解決方法:使用BigDecimal類

技術分享

技術分享

註意:在構造BigDecimal對象時應使用字符串而不是double數值,否則,仍有可能引發計算精度問題。(為什麽會這樣?)

double,不能準確地代表16位有效數以上的數字,在使用BigDecimal時,應用 BigDecimal(String)構造器創建對象才有意義。另外,BigDecimal所創建的是對象,我們不能使用傳統的+、-、*、/等算術運算 符直接對其對象進行數學運算,而必須調用其相對應的方法。方法中的參數也必須是BigDecimal的對象。

動手動腦:

以下代碼的輸出結果是什麽?
int X=100; int Y=200; System.out.println("X+Y="+X+Y); System.out.println(X+Y+"=X+Y");
技術分享 為什麽會有這樣的輸出結果? 技術分享

第一個輸出結果是先輸出X再輸出Y,兩者沒有任何加運算;第二個結果是先計算X+Y的結果輸出再輸出“=X+Y”

(註:部分內容來自於網絡)

課程作業02(關於java的幾點討論)