1.psvm定義的意義
public:保證了方法的訪問權限
static:保證在類未被實體化的時候就能呼叫(加載的時機)
void:不需要回傳值
main:約定俗成的名字
String[] args:提供控制臺傳入的引數
2.代碼塊
代碼塊分為構造代碼塊和靜態(類)代碼塊、區域代碼塊,
構造代碼塊(初始化塊,方法塊)隨著物件的創建而執行,在每次實體化物件時執行,且加載時機優先于建構式,可以在構造代碼塊中初始化成員變數和常量,(常量不賦初值會報錯,JVM不會給他賦初值,但是可以在構造代碼塊中賦初值,)常量的宣告可以放在構造代碼塊的后面,


靜態代碼塊隨類加載而加載,順序上靜態代碼塊優于構造代碼塊,優于建構式,
在類方法/靜態代碼塊中不能使用this,因為static先加載,不可能有物件存在,所以也不可能有物件呼叫方法,靜態代碼塊中可以初始化靜態變數和靜態常量,常量的初始化可以放在靜態構造塊下面,


區域代碼塊:在方法中出現,限定變數生命周期,及早釋放,提高記憶體利用率,
順序練習:
在沒有建構式的情況下,靜態變數是按照陳述句順序執行賦值的,
在有建構式的情況下,訪問物件的靜態變數,結果一定是建構式中傳入的值,因為建構式的順序在最后,
3.常用API
Math.random():回傳【0.0,1.0)之間的浮點數,
System.currentTimeMillis():回傳當前時間(距1970.01.01 0點的毫秒數),經常用來計算一個方法的執行時間,
System.arraycopy(Object[] src,int srcPos,Object[] dest,int destPos,int length):從第一個陣列的起始位置復制到第二個陣列的起始位置,一共復制給定長度個元素,
Date date = new Date(); :回傳當前時間的Date()物件,
date.getTime():回傳毫秒數
SimpleDateFormat formatter = new SimpleDateFormat(格式);:創建一個格式器,
formatter.format(date);:格式化Date物件,回傳一個格式化的字串,
formatter.parse(dateString); :決議字串,回傳一個符合格式的Date,如果大于等于格式,就不會報錯,如果小于格式,就會報ParseException,
Calendar.getInstance() :回傳一個Calendar物件,
calendar.get(欄位名);:回傳日歷物件對應的欄位值,欄位名是Calandar類中定義的常量,注意Calandar.MONTH回傳的是0-11月份,Calandar.HOUR_OF_DAY回傳的是24小時制,
BigDecimal():建構式的引數可以是int,字串,浮點數,BigDecimal可以對超過16位有效位的數進行精確運算,但是保存浮點數時還是非精確的,所以建議用字串保存,
bigDecimal.加減乘除();:devide()如果除以0會報ArithmeticException,
4.包裝類(八種基本資料型別的包裝類)
常用方法:
- 建構式(已棄用)
- 基本型別Value() :回傳基本型別
- 兩個數的最大值/最小值
- parse基本型別:將字串決議為基本型別,常用方法,如果含有不符合的符號會報NumberFormatException,
- toString():
- valueOf(基本型別/字串):回傳包裝型別,和parse基本型別方法都是可以將字串轉換為基本型別的方法,
5.自動裝箱和自動拆箱(java5之后出現)
自動裝箱是指基本型別可以直接賦值為封裝型別,JVM自動完成型別轉換,自動裝箱的程序實際是底層呼叫量valueOf()這個方法,
自動拆箱指封裝型別可以直接賦值為基本型別,自動拆箱的程序實際是底層呼叫XXXValue()這個方法,
6.包裝類的快取問題

以Integer類為例,valueOf()方法回傳的是包裝類,而底層實作采用了快取機制,如果這個簡單型別在[-128,127]之間,就會使用IntegerCache的cache陣列中的物件進行回傳(快取陣列,在[0,255]的下標中存放了每個物件),
而Float和Double類的valueOf()方法沒有使用快取,直接new 了物件, Integer s = new Integer(9) ;//分配堆記憶體,地址,Java不推薦,推薦使用自動裝箱的方法,
Integer t = new Integer(9) ;//分配堆記憶體,地址, Long u = new Long(9) ;//分配堆記憶體,地址 // System.out.println(s==u);//Operator '==' cannot be applied to 'java.lang.Integer', 'java.lang.Long' System.out.println(s==t);//false,兩個不同地址的比較, System.out.println(s.equals(t));//true System.out.println(s.equals(9));//true System.out.println(s.equals(new Integer(9)));
Integer a = 9;//相等于Integer a = Integer.valueOf(9); Integer b = 9; System.out.println(a==b);//true,兩個都是cache陣列的下標地址 a= 128; b= 128; System.out.println(a==b);//false,超過了快取范圍,new的新物件
Character c = 128;
Character d = 128;
System.out.println(c==d);//false,超過快取范圍
Character e = -1;//注意char類的范圍是0~2^16-1,
7.例外
例外是程式執行程序中出現的不正常情況,(開發中的語法錯誤和邏輯錯誤不屬于例外,)
例外分為:
- Error:JVM無法處理的嚴重問題,如記憶體錯誤,資源耗盡,
- Exception:因為編程錯誤和偶然原因出現的一般性問題,一般使用try-catch塊或throw、throws關鍵字處理,如果不處理例外,JVM會在控制臺列印堆疊資訊,并且程式會自動終止,
Exception分為:運行時例外和檢查時例外,(只有RunTimeException子類,沒有CheckedException子類),
運行時例外是編譯器不要求強制處理的例外,通常指編程錯誤,有常見的ArithmeticException、ClassCastException(not instanceof時)、IndexOutOfBoundsException、NullPointerException,
編譯器例外是編譯器要求處理的例外,即一般性例外,如果不處理則程式不允許運行,

8.try-catch-finally 和return順序:
public class test { public int add(int a,int b) { try { return a+b; }catch(Exception e){ System.out.println("catch陳述句塊"); }finally { System.out.println("finally陳述句塊"); } return 0; } public static void main(String[] args) { test t=new test(); System.out.println("和是"+t.add(9, 34));//finally陳述句塊,和是43 } }
當try塊中有return陳述句,又有finally塊時,會先把try塊中的return 回傳值保存到一個堆疊中,當finally塊執行完時,再調出這個堆疊的內容回傳,
public class test { public int add(int a,int b) { try { return a+b; }catch(Exception e){ System.out.println("catch陳述句塊"); }finally { System.out.println("finally陳述句塊"); a=1; } return 0; } public static void main(String[] args) { test t=new test(); System.out.println("和是"+t.add(9, 34));//finally陳述句塊 和是43 } }
在finally塊中又對a進行賦值,但是并沒有影響到堆疊中的內容,只改變了a的值,回傳值沒有變,
如果catch塊中有return陳述句,finally塊中沒有return陳述句,情況也是類似的,
如果finally中也有return陳述句,最侄訓回傳finally的回傳陳述句,
try-catch塊中,可以有多個catch塊,但是只能進入一個catch塊,并列catch塊可以是同級型別,如果有父類例外應該放在最后,catch塊捕捉的是例外物件,
9.throws/throw
throws拋出的是例外的型別,拋出例外可以是多個型別,
throws和throw的區別:
- 撰寫的位置:throw在方法體中,throws在方法宣告上,
- 拋出的型別:throw拋出一個物件,throws拋出的是例外的型別,
- 拋出的個數:throw拋出一個物件,throws可以拋出多個型別,
![]()
10.自定義例外
自定義例外需要繼承Exception類,在有例外的方法體中寫throw 例外物件陳述句,并在這個方法的宣告上標注throws 例外型別,(標注的地方是在引數串列后面),
自定義例外需要重寫無參構造和有參構造(String 例外資訊),
11.練習


javac.exe:編譯.java源檔案為.class位元組碼檔案
java.exe:解釋器,通過java虛擬機來裝載和執行編譯檔案(class檔案)的,Java解釋器是JVM的一部分,Java解釋器用來解釋執行Java編譯器編譯后的程式,java.exe可以簡單看成是Java解釋器,
javap.exe 類分析器 javap命令反匯編一個java位元組代碼檔案, 回傳有關可變部分和成員函式的資訊
javadoc.exe 是java檔案生成器


形參/區域變數不能用修飾符修飾的原因:java修飾符分為兩種,訪問控制修飾符和其他修飾符,
訪問修飾符是用來供其他物件/方法呼叫時用的,但是區域變數只會有方法本身呼叫,已經設定了訪問權限,所以不需要,
其他修飾符中,不能修飾變數的修飾符有abstract(方法和類)、synchronized(方法),
對于static,被static修飾的東西的生命周期是和類一致,而區域變數的宣告周期是和方法一致,
對于final,可以被final修飾,表示這個值是常量,只能被賦值一次,但是必須要賦初值,因為形參是不會被自動賦初值的,
(Java設定成員變數會被自動賦初值,因為成員變數的使用順序是不確定的,可以在方法后被賦值并使用,但是區域變數的執行順序是確定的(僅在方法體內),所以java為了避免程式員出錯,必須給區域變數賦初值,)
(總結來說,成員變數在程式中從來沒有手動賦值,程式不會出錯,而final常量和區域變數從來沒有手動賦值,語法就會報錯,常量可以在方法塊、建構式這些類加載時能運行到的地方賦值,區域變數可以在訪問變數前賦值)


對于transient,是用來在序列化中修飾不需要被序列化的變數,使其不持久化,transient不能用來修飾區域變數,因為它不是成員變數,
對于volatile,是用來在多執行緒中保證變數的值是最新的值,區域變數不存在可見性問題,

對于形參是參考變數型別,我們首先知道雖然形參不能改變實參,但是通過可以修改地址中的物件,形參串列中三個變數都是參考型別,
對于String s,操作是s = s+"t",對于變數和常量的拼接,回傳的是StringBuilder.append()后,new String()的地址,所以改變了形參的值,沒有改變原來的物件(字串物件是不可變的),因此實參s沒有發生改變,
對于StringBuffer s1,操作是s1.append("1"),StringBuffer物件是可變的,所以修改的是s1物件,實參s1發生了改變,
對于StringBuffer s2,操作時s2= new StringBuffer("C1");,沒有改變s2物件的值,修改的是形參的地址,所以實參s2沒有改變,


違反了區域變數不能被生命周期為類的static修飾的道理,


類的初始化順序:
1. 父類靜態代碼塊
2. 子類靜態代碼塊
3. 父類普通代碼塊
4. 父類建構式
5. 子類普通代碼塊
6. 子類建構式


Parent x =new Child();是多型中向上轉型的體現,此時x.i是Parent的變數,x可以呼叫f(),x.f()是Child的方法,但是方法呼叫中用到的變數i,首先會查找方法的區域變數,然后是Child的成員變數,最后是Parent的成員變數,因此x.i=20,x.f()顯示30,Child x1 = (Child)x,是向下轉型的體現,x1可以呼叫f()和g(),編譯期就會確定x1的型別是Child,所以x1.i=30,x1.f()也是就近原則,顯示30,所以最終結果是20 30 20 20,
如果改為Parent x1 = (Child)x;盡管此時也完成了向下轉型,但是又向上轉為Parent,此時x1沒有g()方法,最后結果是20 30 20 30,


類方法中不可以使用this,因為類方法加載的時期中沒有物件存在;類方法中可以呼叫本類和其他類的類方法;類方法中可以創建物件,并呼叫這個的物件的實體方法,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/296187.html
標籤:其他
上一篇:8Java設計模式(持續更新)
下一篇:12Java進階-IO與XML
