摘要:泛型類型對象之間沒有關系,就算之間互為父子關系,也沒有任何關系。泛型類的靜態上下文中類型變量無效。不能捕獲或拋出泛型類的實例。
前言
作為一塊后端沒有太多經驗的年糕,下周要考試了,所以我必須得來好好復習一下我的JAVA進階課/(ㄒoㄒ)/~~。這個學期主要是學了:
泛型
反射
線程
JDBC
JAVA WEB基礎
Servlet
session&cookie
過濾器&監聽器
泛型定義:Java的參數化類型被稱為泛型。
出現原因:JAVA不支持多繼承,雖然有接口,但還是有約束,必須要實現接口的方法。
注意點:
虛擬機沒有泛型類型對象。比如定義了ArrayList
泛型類型對象之間沒有關系,就算T之間互為父子關系,也沒有任何關系。
不能用基本類型實例化類型參數。
運行時類型查詢只適用于原始類型。if( a instanceof Pair
不能創建參數化的數組。聲明類型為Pair
不能實例化類型變量。如new T(), new T[...]或T.class都是無效的。
泛型類的靜態上下文中類型變量無效。
不能捕獲或拋出泛型類的實例。
List定義方式 泛型類l1=new ArrayList (); List l2=new ArrayList (); System.out.println(l1.getClass()==l2.getClass()); //true Collection c= new ArrayList (); if(c instanceof ArrayList ){} //報錯
public class 類名
使用舉例:
Applea1 = new Apple ("蘋果"); Apple a2 = new Apple (5.67);
注意:不能多帶帶用來修飾靜態變量和靜態方法(方法定義具體看后面)。
泛型接口派生類、子類:一定要指明T的類型,或者不寫
public class A1 extends Apple泛型方法{} public class A2 extends Apple{} //等同于
publicvoid ArrayToCollection(T[] a, Collection c){ //... }
方法中的泛型參數無須顯式傳入實際類型參數。編譯器根據實參推斷類型形參的值。
為了讓編譯器能夠準確的推斷出泛型方法中的形參類型,不能產生多種可能性。
比如:我寫了一個選出三個變量中中間的那個值的函數。我可以傳入字符串比較,也可以傳數字,但數字同時有Comparable和Number兩個接口,這樣它無法確定T應該是哪個,應該寫成public static
限定多個用&連接,比如T extends Comparable&Serializable。
泛型必須傳入具體的類型,但如果不確定,就可以用類型通配符,用?表示。?代表可以使任意類型
如:
public void test(List> c){ for (int i = 0; i < c.size(); i++) { System.out.println(c.get(i)); } }
關系:
List>是List的子類,且List
限定:
設置上限:? extends Shape,必須是Shape/Shape的子類才可以。
設置下限:? super Apple,必須是Apple/Apple的父類才可以。
易錯:
1.List>集合是只讀的。不能往List>中添加除null的任何東西。
[原因]我們假設可以添加的話:
Listis = Arrays.asList("one", "two", "three"); List> list=is; list.add(new String("four"));//Ok list.add(new Integer(4));//如果假設成立,則是OK的
那么混入了其他類型的變量我們也沒有辦法判斷,所以要禁止添加。
2.?不是類型變量,不可以代替類型來使用。
public static void swap(Pair> p){ ? t=p.getFirst(); //錯誤 }類的加載
定義:當程序主動使用某個類時,如果該類還未被加載到內存中,系統會通過加載、連接、初始化三個步驟來該類進行初始化,如果沒有意外,JVM將會連續完成這三個步驟,即類的加載/初始化。
三個步驟:
加載——找到.class文件并把這個文件包含的字節碼加載到內存中
連接——分為驗證、準備和解析
初始化——類中靜態屬性和靜態塊的執行
JVM進程終止的情況:
運行到最后正常結束
運行到使用System.exit()/Runtime.getRuntime().exit()
遇到未捕獲的異常或錯誤
所在平臺強制結束JVM進程。
步驟-加載調用ClassLoader的findClass方法,可從不同來源中加載類的二進制數據,通常由如下來源:
本地文件系統
JAR包,例:JDBC編程用到的數據庫驅動類
網絡加載,例:Applet
其他文件生成,例:JSP文件生成對應的Class類
運行時計算生成,例:動態代理技術
步驟-連接驗證:檢查被加載的類是否有正確的內部結構,并和其他類一致。包括文件格式驗證、元數據驗證、字節碼驗證、符合引用驗證
準備:為類的靜態屬性分配內存和指定初始值(通常情況下為默認初始值)。這些變量所使用的的內存在方法區被分配。
解析:將常量池中的符號引用替換為直接引用的過程。主要針對類和接口、字段、類方法、接口方法、方法類型、方法句柄和調用點限定符。
注意:
public static int value = 123,變量value在準備階段的值是0,注意是分配默認值。假設一個變量的定義如下:
public static final int value = 123;變量value在準備階段的值是123,因為這是一個常量,存放在方法區的常量池中。
解析過程不一定發生在初始化之前,可以發生在初始化之后再開始。
步驟-初始化編譯器自動收集類中所有類變量的賦值動作和靜態語句塊中的語句,收集的順序由語句在源文件中出現的順序所決定的。
public class Test { static int a = 5; //準備階段的初值為0,初始化賦值為5 static int b; //準備階段的初值為0 static int c; //準備階段的初值為0 static{ //初始化階段的賦值為6 b = 6; } }
初始化一個類的步驟
類沒有被加載,先加載并連接該類。
類的直接父類還被初始化,先初始化其直接父類。
類中有初始化語句,系統依次執行這些初始化語句。
初始化類的5中情況
創建類的實例;讀取或設置一個類的靜態字段(放入常量池的除外);調用一個類的靜態方法。
使用java.lang.reflect包方法進行反射調用(如果沒有進行過初始化)。例:Class.forName("SuperClass")
父類沒有進行初始化,則需要先觸發父類的初始化
虛擬機啟動,用戶需制定一個執行的主類(包含main()方法的那個類),虛擬機會先初始化這個類。
來自JDK1.7:一個MethodHandle實例最后的解析結果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,且句柄所對應的類沒有進行初始化。
注意
使用ClassLoader類的loadClass()加載某個類時并不會執行該類的初始化。
如果final類型的靜態屬性的值不能在編譯時得到,必須等到運行時才能確定該屬性的值,就會觸發初始化。
類加載器將.class文件加載到內存中,生成對應的java.lang.Class對象。
注意:
只有類是同一個類加載器加載才有可能等于(包含Class對象的equals方法、instanceof)。
類加載器分類
Bootstrap ClassLoader:根類加載器,加載Java的核心類。
Extension ClassLoader:擴展類加載器,加載JRE的擴展目錄(JAVA_HOME/jre/lib/ext)中的JAR的類包。
System ClassLoader:系統類加載器,加載命令java中的classpath選擇的JAR包和類路徑。
類加載機制
全盤負責:一個類加載器負責加載Class和它的依賴Class,除非顯示使用另一個加載器。
父類委托:先讓父類加載該Class,在父類加載器無法加載時從自己的類路徑中加載。(類加載器之間的父子關系不是繼承上的父子關系,是類加載器實例之間的關系。
)
緩存機制:當程序中需要Class時,先從緩存中搜尋,緩存中不存在時,才重讀該類對應的二進制數據,并將其轉換為Class對象,并存入到cache。
反射使用場合:編譯的時候無法獲悉類型,依靠運行時信息發現,這時就采用反射。
獲取Class的方法Class類的forName()靜態方法(可能拋出ClassNotFoundException)。
調用某個類的class屬性。
調用某個對象的getClass()。
獲取構造函數
Constructor
Constructor>[] getConstructors()獲取Class對象表示類的所有public構造器。
Constructor
Constructor>[] getDeclaredConstructors()獲取Class對象表示類的所有構造器。
創建對象Class對象的newInstance()方法:要求該Class對象有默認的構造方法。
調用Constructor對象的newInstance()。
調用方法Class對象的getMethods()方法/getMethod()方法,再調用Method Object invoke(Object obj, Object...args),該方法中的obj是執行該方法的主調,后面跟著的是參數。
訪問屬性獲得Class對象后,通過該Class對象的getFields()方法或getDeclaredFields()方法來獲取全部屬性或指定屬性。
Field nameField = personClazz.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(p , "Yeeku.H.Lee");
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/69380.html
摘要:從白天到晚上,不是在學就是在學的路上,從測試理論到實戰操作,大大小小的問題,在群里前輩的幫助下,總是能很快解決。慢慢的,測試方法,用例設計,測試,測試,接口測試。大概面試了一周多,我就拿下了的。 ...
摘要:后來知道有了院賽,學長說刷院和杭電就可,我就一直刷院,到最后比賽前院的前五十道基本做完,杭電也弄了十來道,就這樣草草參加比賽了。 博客主頁: https://b...
摘要:解放碑的鐘聲響起,年結束,迎來了新的一年時間本來無所謂結點,只是人類為其賦予了意義。生活就是這樣,總結反思,再度起航。這并不算是自己的愿望,這是大家的愿望。所以,正值研究生一年級的我,很清楚自己這一年想要什么,也下定決心去實現它加油。 解放碑的鐘聲響起,2018年結束,迎來了新的一年2019.時間本來無所謂結點,只是人類為其賦予了意義。生活就是這樣,總結反思,再度起航。作為一個新的開始...
摘要:需要注意的是用矩陣形式如行列表示二維數組,是邏輯上的概念,能形象地表示出行列關系。再次強調二維數組名如是指向行的。一維數組名如是指向列元素的。 哈嘍!這里是一只派大鑫,不是派大星。本著基礎不牢,地動山搖的學習態度,從基礎的C語言語法講到算法再到更高級的語法及框架的學習。更好地讓同樣熱愛編...
閱讀 1447·2021-11-11 16:54
閱讀 9419·2021-11-02 14:44
閱讀 2384·2021-10-22 09:53
閱讀 3269·2019-08-30 11:18
閱讀 1958·2019-08-29 13:29
閱讀 2015·2019-08-27 10:58
閱讀 1634·2019-08-26 11:38
閱讀 3527·2019-08-26 10:31