標籤:工程 輸出 使用 情況 成員 精度 main方法 兩種 tip
質疑1:
一個Java類檔案中真的只能有一個公有類嗎?
建立Test01.java,輸入以下代碼
1 public class Test01 2 { 3 public static void main(String args[]) 4 { 5 6 } 7 8 public class Innerclass 9 {10 11 }12 }
編譯
編譯成功,產生了兩個.class檔案
若將內部類名也設為Test01,則編譯不通過
則可以這樣說:
因為內部類作為外部類的一個成員而存在,類的成員可以用public修飾
在一個.java源檔案中,最多隻能有一個與源檔案同名的public類
2.質疑2:
主方法的固定格式:public static void main( String args[] )
能否把main()方法的傳回值由 void 改為 int?
實踐出真知
建立Test02.java,輸入以下代碼
1 public class Test022 {3 public static int main(String args[])4 {5 return 0; 6 }7 }
將void改成int,並添加相應的傳回值
編譯,編譯通過
再來運行試試,結果報錯
void表示main方法沒有傳回值,沒有傳回值的原因是因為Java不需要main方法向作業系統返回退出資訊。如果main方法正常退出,那麼Java應用程式的結束代碼為0,表示成功的運行了程式。
除此之外,主方法其他部分都不能改動,唯一可改變的是String[] args可以寫成String args[],以及args的名稱可以改變
3.思索:
什麼是靜態方法?
無須建立對象即可使用的方法。
為什麼java規定作為程式進入點的main() 方法靜態?
答:正因為main方法是靜態,JVM調用這個方法就不需要建立任何包含這個main方法的執行個體。
如果main方法不聲明為靜態,JVM就必須建立main類的執行個體,因為構造器可以被重載,JVM就沒法確定調用哪個main方法。
靜態方法和待用資料載入到記憶體就可以直接調用而不需要像執行個體方法一樣建立執行個體後才能調用,如果main方法是靜態,那麼它就會被載入到JVM上下文中成為可執行檔方法
4.每個變數都有一個“有效”的地區(稱為“範圍”),出了這個地區,變數將不再有效。
請看以下範例程式碼,輸出結果是什麼?
1 public class Test03 2 { 3 private static int value=1; 4 5 public static void main(String args[]) 6 { 7 int value=2; 8 System.out.println(value); 9 }10 }
輸出結果
Java變數遵循“同名變數的屏蔽原則
每個變數都有一個“有效”的地區(稱為“範圍”),出了這個地區,變數將不再有效,同名的變數在指定的範圍內有自動屏蔽的原則。即局部變數可以與全域變數同名,在函數內引用這個變數時,會用到同名的局部變數,而不會用到全域變數。
5.Java中的類型轉換
運行以下代碼
1 public class Test04 2 3 { 4 5 public static void main(String args[]) 6 7 { 8 9 System.out.println("0.05 + 0.01 = " + (0.05 + 0.01));10 11 System.out.println("1.0 - 0.42 = " + (1.0 - 0.42));12 13 System.out.println("4.015 * 100 = " + (4.015 * 100));14 15 System.out.println("123.3 / 100 = " + (123.3 / 100));16 17 }18 }
運行結果
精度損失原因:
float 和double類型主要是為科學計算和工程計算而設計的,他們執行二進位浮點運算,這兩種類型在電腦中的儲存分為三部分:符號位、指數為、尾數部分。
資料以二進位儲存在電腦時,會出現無線迴圈系列,在資料轉化中會出現錯誤。十進位不能準確的表示1/3,同樣二進位不能精確的表示1/10,大部分浮點數儲存在計算 機中都只是一個近似值。
java中十進位與二進位轉化時存在問題,double類型的數值佔用64bit,即64個位元,除去最高位表示正負符號的位,在最低 位上一定會與實際資料存在誤差,簡單來說就是我們給出的數值,在 大多數情況下需要比64bit更多的位元才能準確表示出來(甚至是需要無窮多位),而double類型的數值只有64bit,後面捨去的位元一定會帶來誤差,無法得到“數學上精確”的結果。
6怎樣處理精度損失?
解決方案——使用BigDecimal類
1 import java.math.BigDecimal; 2 3 public class TestBigDecimal 4 { 5 public static void main(String[] args) 6 { 7 BigDecimal f1 = new BigDecimal("0.05"); 8 BigDecimal f2 = BigDecimal.valueOf(0.01); 9 BigDecimal f3 = new BigDecimal(0.05);10 System.out.println("下面使用String作為BigDecimal構造器參數的計算結果:");11 System.out.println("0.05 + 0.01 = " + f1.add(f2));12 System.out.println("0.05 - 0.01 = " + f1.subtract(f2));13 System.out.println("0.05 * 0.01 = " + f1.multiply(f2));14 System.out.println("0.05 / 0.01 = " + f1.divide(f2));15 System.out.println("下面使用double作為BigDecimal構造器參數的計算結果:");16 System.out.println("0.05 + 0.01 = " + f3.add(f2));17 System.out.println("0.05 - 0.01 = " + f3.subtract(f2));18 System.out.println("0.05 * 0.01 = " + f3.multiply(f2));19 System.out.println("0.05 / 0.01 = " + f3.divide(f2));20 }21 }
運行結果:
在構建BigDecimal對象時應使用字串而不是double數值,否則,仍有可能引發計算精度問題。(為什麼會這樣呢?)
double+、-不能準確的代表BigDecimal(String) 16位有效數以上的數字在使用BigDecimal時,應用*、/構造器建立對象才有意義。BigDecimal所建立的對象不能使用傳統的等算術運算子直接對其對象進行數學運算,而必須調用相對應的方法。方法中的參數必須是BigDecimal的對象。
7.以下代碼的輸出結果是什嗎?
1 int X=100;2 int Y=200;3 System.out.println("X+Y="+X+Y);4 System.out.println(X+Y+"=X+Y");
運行結果:
原因:
因為雙引號表示是String類型,String+int類型自動轉換,int轉String,100自動轉換為String類型,對於兩個字串,+執行的是字串的串連操作,此時若輸出,結果是 X+Y=100,然後繼續進行,200轉換為String類型,所以輸出的是X+Y=100200
從左往右,首先是100+200,兩個變數都是int類型,所以進行計算,此時執行的是數學的加法,得到int類型的300,然後int類型的300與String類型的“=X+Y”做運算,int類型自動轉換為String,然後+執行字串串連操作,得到300=X+Y
java學習筆記