2020-10-23 集合+序列化+递归+多线程+泛型+枚举+单例+反射小记
【集合】:
| Collection接口 (Collection接口是集合類的根接口,Java中沒(méi)有提供這個(gè)接口的直接的實(shí)現(xiàn)類。但是卻讓其被繼承產(chǎn)生了兩個(gè)接口,就是Set和List) | ||
| Set接口(無(wú)序集合,不允許重復(fù),檢索元素效率低下,刪除和插入效率高,插入和刪除不會(huì)引起元素位置改變) | HashSet(以哈希表的形式存放元素,插入刪除速度很快) | LinkedHashSet(有序集合) |
| SortedSet | TreeSet(排序集合) | |
| EnumSet | ? | |
| Queue(隊(duì)列) | ... | ? |
| ... | ? | |
| List接口(有序集合,可以有重復(fù)元素,提供了按索引訪問(wèn)的方式。和數(shù)組類似,List可以動(dòng)態(tài)增長(zhǎng),查找元素效率高,插入刪除元素效率低,因?yàn)闀?huì)引起其他元素位置改變) | Vector(線程安全的,但是效率低) | Stack(線程安全的,但是效率低;是Vector的一個(gè)子類,它實(shí)現(xiàn)了標(biāo)準(zhǔn)的后進(jìn)先出堆棧) 線程不安全的類都可以配合Collections得到線程安全的類 |
| ArrayList(動(dòng)態(tài)數(shù)組) | ? | |
| LinkedList(鏈表、隊(duì)列、堆棧) | ? | |
| Map(無(wú)序集合) | |
| HashMap (Key不允許重復(fù);快速訪問(wèn),取得數(shù)據(jù)的順序隨機(jī),非同步) | LinkedHashMap(有序集合,比HashMap慢,保存了記錄的插入順序,遍歷時(shí)先得到的記錄肯定是先插入的,有HashMap的全部特性) |
| Hashtable(Key不允許重復(fù);是HashMap的線程安全版,支持線程的同步,即同一時(shí)刻只有一個(gè)線程能寫Hashtable,效率低) ConcurrentHashMap線程安全且鎖分離 | Properties (Properties是Hashtable的子類。它用于維護(hù)鍵的列表,其中鍵是String,值也是String。) |
| SortedMap | TreeMap(排序集合,默認(rèn)是按鍵值的升序排序,非同步;實(shí)現(xiàn)SortedMap接口,能把保存的記錄根據(jù)鍵排序) |
| WeakHashMap | ? |
| IdentityHashMap | ? |
| EnumMap | ? |
?
//Set集合(遍歷方式:迭代器迭代/forEach循環(huán)遍歷,與list方式一樣):Set set = new HashSet();set.add("Bernadine");set.add("Clara"); /*set接口中不能加入重復(fù)元素,但是可以排序--HashSet散列存放;TreeSet排序集合*/Set set= new TreeSet(set); //排序集合:根據(jù)內(nèi)容自動(dòng)排序(不是按照插入順序) // List集合: /*ArrayList和Vector比較:ArrayList采用異步處理的方式,性能高,屬于非線程安全;Vector采用同步處理的方式,性能低,屬于線程安全。*/ /*ArrayList和LinkedList在用法上沒(méi)有區(qū)別,但是在功能上還是有區(qū)別的。LinkedList經(jīng)常用在增刪操作較多而查詢操作很少的情況下,ArrayList則相反。*/List list = new Vector(); //java.util.Vector;List<Object> list=new ArrayList<Object>(); // java.util.ArrayList; --使用泛型指定類型為 Object(不使用泛型:List list=new ArrayList();)list.add(“***”); //寫入數(shù)據(jù)list.remove(0); //刪除當(dāng)前元素list.indexOf("a"); //查找制定的對(duì)象是否存在(返回int)list.isEmpty(); //判斷集合是否為空(返回booole)/*遍歷list集合-1(使用迭代器迭代),Iterator是專門的迭代輸出接口,迭代輸出就是將元素一個(gè)個(gè)進(jìn)行判斷,判斷其是否有內(nèi)容,如果有則把內(nèi)容取走*/Iterator<User> it=list.iterator(); //不能在迭代輸出的時(shí)候進(jìn)行iter.remove()刪除操作,會(huì)報(bào)錯(cuò)while (it.hasNext()) { //使用hasNext()檢查序列中是否還有元素(判斷是否下一個(gè)元素為空)User user1 = (User) it.next(); // 使用next()獲得序列中的下一個(gè)元素System.out.println("username:"+user1.getUsername());}/*遍歷list集合-2 (forEach循環(huán)遍歷)*/for (String s : list) { System.out.println(s);}/*遍歷list集合-3 (for循環(huán)遍歷)*/for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i).getUsername());} //map集合:Map<String, User> map=new HashMap<String, User>(); //java.util.HashMap; --使用泛型指定類型為String,User(不使用泛型:Map map=new HashMap();)map.containsKey(users.getUsername()); //containsKey()方法用于檢查特定鍵是否被映射到 HashMap,它將key元素作為參數(shù),如果該元素在map中映射,則返回Truemap.put(users.getUsername(), users); //寫入數(shù)據(jù)map.put("1", 1);int i = (int) map.get("1"); //提取鍵值map.containsKey("1"); //看key是不是存在 返回booleanmap.containsValue(1); //看value是不是存在,返回boolean/*遍歷map集合-1 (map無(wú)法直接使用Iterator遍歷,需要先獲取set視圖)*/Set<String> set=map.keySet(); //第一種:map.keySet()可以將所有的鍵都提取出來(lái),返回的是一個(gè)Set集合Iterator<String> it=set.iterator(); //使用set集合調(diào)用迭代器Iterator來(lái)進(jìn)行輸出while (it.hasNext()) {String key = (String) it.next();User user=map.get(key); System.out.println("username:"+user.getUsername());}Set set=map.entrySet(); //第二種:使用EntrySet的IteratorIterator it = set.iterator();while(it.hasNext()){Entry e =(Entry) it.next();System.out.println(e.getKey()+":"+e.getValue());} /*遍歷map集合-2 */for (String key : map.keySet()) { //第一種:forEach直接使用HashMap的keysetSystem.out.println("key:"+key+"value:"+map.get(key));}for(Entry<String, String> entry : map.entrySet()){ //第二種:forEach循環(huán)遍歷HashMap的entrySetSystem.out.println("key:"+entry.getKey()+"? value:"+entry.getValue());}/*遍歷map集合-3(只取到value) */for (String s : map.values()) { //map.values();是返回所有值,返回是一個(gè)Collection 集合System.out.println(s);}【序列化】:
? ?IO流示例:CSDN博客?https://blog.csdn.net/qq_36095102/article/details/99735418
? ?字符流和字節(jié)流區(qū)別:
? ? ? //字符流處理的單元為2個(gè)字節(jié)的Unicode字符,分別操作字符、字符數(shù)組或字符串,而字節(jié)流處理單元為1個(gè)字節(jié),操作字節(jié)和字節(jié)數(shù)組;
? ? ? //讀文本的時(shí)候用字符流,例如txt文件,讀非文本文件的時(shí)候用字節(jié)流,例如mp3;
? ? ? //字節(jié)流提供了處理任何類型的IO操作的功能,但不能直接處理Unicode字符,而字符流就可以。
? ?緩沖流原理:
? ? ? 1)緩沖區(qū)的出現(xiàn):提高了流的讀寫效率,所以在緩沖區(qū)創(chuàng)建前,要先創(chuàng)建流對(duì)象。即先將流對(duì)象初始化到構(gòu)造函數(shù)中。
? ? ? 2)緩沖技術(shù)原理:此對(duì)象中封裝了數(shù)組,將數(shù)據(jù)存入,再一次性取出。
? ? ? 3)寫入流緩沖區(qū)BufferedWriter?
? ?序列化和反序列化:
? ? ? ?// 將程序中的對(duì)象寫入文件,之后再?gòu)奈募邪褜?duì)象讀出來(lái)重新建立,這就是所謂的對(duì)象序列化。Java中引入它主要是為了RMI(Remote Method Invocation)和Java Bean所用。
? ? ? ?/*Externalizable接口繼承自 Serializable接口,實(shí)現(xiàn)Externalizable接口的類完全由自身來(lái)控制序列化的行為,而僅實(shí)現(xiàn)Serializable接口的類可以采用默認(rèn)的序列化方式 */?
? ? ? ?/*只有實(shí)現(xiàn)了Serializable和Externalizable接口的類的對(duì)象才能被序列化。 */
? ? ? ?/*序列化(Serialization):是將對(duì)象的狀態(tài)信息轉(zhuǎn)換為可以存儲(chǔ)或傳輸?shù)男问降倪^(guò)程;序列化時(shí),對(duì)象將其當(dāng)前狀態(tài)寫入到臨時(shí)或持久性存儲(chǔ)區(qū);可以通過(guò)從存儲(chǔ)區(qū)中讀取或反序列化對(duì)象的狀態(tài),重新創(chuàng)建該對(duì)象。*/
【遞歸 (Recursion)?】:
? ?//使用范圍:當(dāng)一個(gè)功能被重復(fù)使用,而每一次使用該功能時(shí)的參數(shù)不確定,都由上次的功能元素結(jié)果來(lái)確定。其實(shí)遞歸就是在棧內(nèi)存中不斷的加載同一個(gè)函數(shù)。
【多線程 (Multi Thread)?】:
? ? ? 多線程定義:指的是這個(gè)程序(一個(gè)進(jìn)程)運(yùn)行時(shí)產(chǎn)生了不止一個(gè)線程(一個(gè)進(jìn)程在其執(zhí)行過(guò)程中可以產(chǎn)生多個(gè)線程)
? ? ? 進(jìn)程:是程序的一次動(dòng)態(tài)執(zhí)行過(guò)程
? ? ? 線程:是進(jìn)程中執(zhí)行運(yùn)算的最小單位,一個(gè)進(jìn)程在其執(zhí)行過(guò)程中可以產(chǎn)生多個(gè)線程,而線程必須在某個(gè)進(jìn)程內(nèi)執(zhí)行。
? ? ? 多線程:線程是進(jìn)程內(nèi)部的一個(gè)執(zhí)行單元,可完成一個(gè)獨(dú)立的任務(wù)的順序控制流程,如果在一個(gè)進(jìn)程中同時(shí)運(yùn)行了多個(gè)線程,用來(lái)完成不同的工作,則稱之為多線程。
? ? ? 并行:多個(gè)cpu實(shí)例或者多臺(tái)機(jī)器同時(shí)執(zhí)行一段處理邏輯,是真正的同時(shí)。
? ? ? 并發(fā):通過(guò)cpu調(diào)度算法,讓用戶看上去同時(shí)執(zhí)行,實(shí)際上從cpu操作層面不是真正的同時(shí)。并發(fā)往往在場(chǎng)景中有公用的資源,那么針對(duì)這個(gè)公用的資源往往產(chǎn)生瓶頸,我們會(huì)用TPS或者QPS來(lái)反應(yīng)這個(gè)系統(tǒng)的處理能力。
? ? ? 線程安全:經(jīng)常用來(lái)描繪一段代碼。指在并發(fā)的情況之下,該代碼經(jīng)過(guò)多線程使用,線程的調(diào)度順序不影響任何結(jié)果。這個(gè)時(shí)候使用多線程,我們只需要關(guān)注系統(tǒng)的內(nèi)存,cpu是不是夠用即可。反過(guò)來(lái),線程不安全就意味著線程的調(diào)度順序會(huì)影響最終結(jié)果
? ? ? 同步:Java中的同步指的是通過(guò)人為的控制和調(diào)度,保證共享資源的多線程訪問(wèn)成為線程安全,來(lái)保證結(jié)果的準(zhǔn)確。
? ? ? 目的:就是"最大限度地利用CPU資源",當(dāng)某一線程的處理不需要占用CPU而只和I/O,OEMBIOS等資源打交道時(shí),讓需要占用CPU資源的其它線程有機(jī)會(huì)獲得CPU資源。從根本上說(shuō),這就是多線程編程的最終目的。要通過(guò)不斷切換需要運(yùn)行的線程讓其運(yùn)行的方式就叫并發(fā)(concurrent)。而在多CPU系統(tǒng)中,可以讓兩個(gè)以上的線程同時(shí)運(yùn)行,這種可以同時(shí)讓兩個(gè)以上線程同時(shí)運(yùn)行的方式叫做并行(parallel)。
? ? ? 線程完整的生命周期:
? ? ?? ? ? 新建狀態(tài): 一個(gè)新產(chǎn)生的線程從新狀態(tài)開始了它的生命周期。它保持這個(gè)狀態(tài)直到程序start這個(gè)線程。
? ? ?? ? ? 運(yùn)行狀態(tài):當(dāng)一個(gè)新狀態(tài)的線程被start以后,線程就變成可運(yùn)行狀態(tài),一個(gè)線程在此狀態(tài)下被認(rèn)為是開始執(zhí)行其任務(wù)
? ? ? ? ? ?就緒狀態(tài):當(dāng)一個(gè)線程等待另外一個(gè)線程執(zhí)行一個(gè)任務(wù)的時(shí)候,該線程就進(jìn)入就緒狀態(tài)。當(dāng)另一個(gè)線程給就緒狀態(tài)的線程發(fā)送信號(hào)時(shí),該線程才重新切換到運(yùn)行狀態(tài)。
? ? ? ? ? ?休眠狀態(tài): 由于一個(gè)線程的時(shí)間片用完了,該線程從運(yùn)行狀態(tài)進(jìn)入休眠狀態(tài)。當(dāng)時(shí)間間隔到期或者等待的事件發(fā)生了,該狀態(tài)的線程切換到運(yùn)行狀態(tài)。
? ? ?? ? ? 終止?fàn)顟B(tài): 一個(gè)運(yùn)行狀態(tài)的線程完成任務(wù)或者其他終止條件發(fā)生,該線程就切換到終止?fàn)顟B(tài)。
? ? ? 多線程三種實(shí)現(xiàn)方法:
? ? ?? ? ? 1)繼承Thread類,重寫run()方法
? ? ? ? ? ? 2)實(shí)現(xiàn)Runnable接口,并實(shí)現(xiàn)該接口的run()方法
? ? ? ? ? ? 3)使用ExecutorService、Callable、Future實(shí)現(xiàn)有返回結(jié)果的多線程(實(shí)現(xiàn)Callable接口,重寫call()方法)
? ? ? ? ? ? 其中前兩種方式線程執(zhí)行完后都沒(méi)有返回值,只有最后一種是帶返回值的。run()方法可以產(chǎn)生必須退出的標(biāo)志來(lái)停止一個(gè)線程.??
? ? ? 同步的實(shí)現(xiàn)方面有兩種:
? ? ? ? ? ? synchronized、wait與notify
? ? ? 繼承Thread類的方法盡管被我列為一種多線程實(shí)現(xiàn)方式,但Thread本質(zhì)上也是實(shí)現(xiàn)了Runnable接口的一個(gè)實(shí)例,它代表一個(gè)線程的實(shí)例,并且,啟動(dòng)線程的唯一方法就是通過(guò)Thread類的start()實(shí)例方法。start()方法是一個(gè)native方法,它將啟動(dòng)一個(gè)新線程,并執(zhí)行run()方法。這種方式實(shí)現(xiàn)多線程很簡(jiǎn)單,通過(guò)自己的類直接extend Thread,并復(fù)寫run()方法,就可以啟動(dòng)新線程并執(zhí)行自己定義的run()方法。例如:
//繼承Thread類,重寫run()方法 public class MyThread extends Thread { ?public void run() { ?System.out.println("MyThread.run()"); ?} ? } ?//在合適的地方啟動(dòng)線程如下:MyThread myThread1 = new MyThread(); ?MyThread myThread2 = new MyThread(); ?myThread1.start(); ?myThread2.start(); ?? ? ? 設(shè)計(jì)4個(gè)線程:其中兩個(gè)線程每次對(duì)j增加1,另外兩個(gè)線程對(duì)j每次減少1。寫出程序。
? ? ? 以下程序使用內(nèi)部類實(shí)現(xiàn)線程,對(duì)j增減的時(shí)候沒(méi)有考慮順序問(wèn)題。
【泛型 (Generics)?】:
泛型定義:
? ? ? 本質(zhì)是參數(shù)化類型,當(dāng)類中操作的引用類型不確定時(shí)引用 (這樣可以避免強(qiáng)轉(zhuǎn)的麻煩,而且將運(yùn)行問(wèn)題轉(zhuǎn)移到的編譯時(shí)期)
? ? ? //也就是說(shuō)操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù),使代碼可以應(yīng)用于多種類型
? ? ? //將對(duì)象的類型作為參數(shù),指定到其他類或者方法上,從而保證類型轉(zhuǎn)換的安全性和穩(wěn)定性,這就是泛型。
語(yǔ)法:
? ? ? 類1或者接口<類型實(shí)參> 對(duì)象=new 類2<類型實(shí)參>( );
??????例:List<NewTitle> list=new ArrayList<NewTitle>( );
【枚舉(enum)】:
定義:指由一組固定的常量組成的類型(使用關(guān)鍵字enum定義,繼承java.lang.Enum)
? ? ? ? ? ?Enum 一般用來(lái)表示一組相同類型的常量
【單例模式 (SingletonPattern) 】:
? ? ? 參考: https://www.runoob.com/design-pattern/singleton-pattern.html
? ? ? 單例模式:常見(jiàn)23種設(shè)計(jì)模式之單例模式。
? ? ? 3個(gè)特點(diǎn):
?? ?①、單例類只能有一個(gè)實(shí)例。
?? ?②、單例類必須自己創(chuàng)建自己的唯一實(shí)例。
?? ?③、單例類必須給所有其他對(duì)象提供這一實(shí)例。
? ? ? ?? ?(構(gòu)造函數(shù)是私有的,方法是static的)
??????定義:一個(gè)類有且僅有一個(gè)實(shí)例,并且自行實(shí)例化向整個(gè)系統(tǒng)提供。
??????目的:是保證整個(gè)應(yīng)用中只存在類的唯一個(gè)實(shí)例。
? ? ? ? ? ? ? ? ?比如我們?cè)谙到y(tǒng)啟動(dòng)時(shí),需要加載一些公共的配置信息,對(duì)整個(gè)應(yīng)用程序的整個(gè)生命周期中都可見(jiàn)且唯一,這時(shí)需要設(shè)計(jì)成單例模式。如:spring容器,session工廠,緩存,數(shù)據(jù)庫(kù)連接池等等。
??????優(yōu)點(diǎn):該類只存在一個(gè)實(shí)例,節(jié)省系統(tǒng)資源;對(duì)于需要頻繁創(chuàng)建銷毀的對(duì)象,使用單例模式可以提高系統(tǒng)性能。
??????缺點(diǎn):不能外部實(shí)例化(new),調(diào)用人員不清楚調(diào)用哪個(gè)方法獲取實(shí)例時(shí)會(huì)感到迷惑,尤其當(dāng)看不到源代碼時(shí)。
??????意圖:保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問(wèn)它的全局訪問(wèn)點(diǎn)。
??????主要解決:一個(gè)全局使用的類頻繁地創(chuàng)建與銷毀。
??????何時(shí)使用:當(dāng)您想控制實(shí)例數(shù)目,節(jié)省系統(tǒng)資源的時(shí)候。
? ? ? 意義:單例模式確保某個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。在計(jì)算機(jī)系統(tǒng)中,線程池、緩存、日志對(duì)象、對(duì)話框、打印機(jī)、顯卡的驅(qū)動(dòng)程序?qū)ο蟪1辉O(shè)計(jì)成單例。這些應(yīng)用都或多或少具有資源管理器的功能。每臺(tái)計(jì)算機(jī)可以有若干個(gè)打印機(jī),但只能有一個(gè)Printer Spooler,以避免兩個(gè)打印作業(yè)同時(shí)輸出到打印機(jī)中。每臺(tái)計(jì)算機(jī)可以有若干通信端口,系統(tǒng)應(yīng)當(dāng)集中管理這些通信端口,以避免一個(gè)通信端口同時(shí)被兩個(gè)請(qǐng)求同時(shí)調(diào)用。總之,選擇單例模式就是為了避免不一致狀態(tài),避免政出多頭。
? ? ? 分類:
? ? ? ? ? ? 懶漢式單例(實(shí)現(xiàn)線程安全三種方式:在getInstance方法上加同步、雙重檢查鎖定、靜態(tài)內(nèi)部類)
? ? ? ? ? ? 餓漢式單例
? ? ? ? ? ? 登記式單例(可忽略)
? ? ? ? ? ?( 始終是一個(gè)對(duì)象實(shí)例.它對(duì)外不提供構(gòu)造函數(shù),因此我們不能夠同時(shí)產(chǎn)生多個(gè)對(duì)象. )
? ? ? ? ? ?參考:https://blog.csdn.net/emira_j/article/details/52447390
? ? ? 應(yīng)用實(shí)例:Windows 是多進(jìn)程多線程的,在操作一個(gè)文件的時(shí)候,就不可避免地出現(xiàn)多個(gè)進(jìn)程或線程同時(shí)操作一個(gè)文件的現(xiàn)象,所以所有文件的處理必須通過(guò)唯一的實(shí)例來(lái)進(jìn)行。
你用杯子喝可樂(lè),喝完了不刷,繼續(xù)去倒果汁喝,就是單例。
你用杯子喝可樂(lè),直接扔了杯子,換個(gè)杯子去倒果汁喝,就是多例。
①. 什么是單例多例:
?? ?所謂單例就是所有的請(qǐng)求都用一個(gè)對(duì)象來(lái)處理,比如我們常用的service和dao層的對(duì)象通常都是單例的,而多例則指每個(gè)請(qǐng)求用一個(gè)新的對(duì)象來(lái)處理,比如action;
②. 如何產(chǎn)生單例多例:
?? ?在通用的SSH中,單例在spring中是默認(rèn)的,如果要產(chǎn)生多例,則在配置文件的bean中添加scope="prototype";
③. 為什么用單例多例:
?? ?之所以用單例,是因?yàn)闆](méi)必要每個(gè)請(qǐng)求都新建一個(gè)對(duì)象,這樣子既浪費(fèi)CPU又浪費(fèi)內(nèi)存;
?? ?之所以用多例,是為了防止并發(fā)問(wèn)題;即一個(gè)請(qǐng)求改變了對(duì)象的狀態(tài),此時(shí)對(duì)象又處理另一個(gè)請(qǐng)求,而之前請(qǐng)求對(duì)對(duì)象狀態(tài)的改變導(dǎo)致了對(duì)象對(duì)另一個(gè)請(qǐng)求做了錯(cuò)誤的處理;
?? ?用單例和多例的標(biāo)準(zhǔn)只有一個(gè):
?????? ?當(dāng)對(duì)象含有可改變的狀態(tài)時(shí)(更精確的說(shuō)就是在實(shí)際應(yīng)用中該狀態(tài)會(huì)改變),則多例,否則單例;
④. 何時(shí)用單例?何時(shí)用多例?
?? ?對(duì)于struts2來(lái)說(shuō),action必須用多例,因?yàn)閍ction本身含有請(qǐng)求參數(shù)的值,即可改變的狀態(tài);
?? ?而對(duì)于STRUTS1來(lái)說(shuō),action則可用單例,因?yàn)檎?qǐng)求參數(shù)的值是放在actionForm中,而非action中的;
?? ?另外要說(shuō)一下,并不是說(shuō)service或dao一定是單例,標(biāo)準(zhǔn)同第3點(diǎn)所講的,就曾見(jiàn)過(guò)有的service中也包含了可改變的狀態(tài),同時(shí)執(zhí)行方法也依賴該狀態(tài),但一樣用的單例,這樣就會(huì)出現(xiàn)隱藏的BUG,而并發(fā)的BUG通常很難重現(xiàn)和查找;
【反射 (Reflection)?】:
? ? ? 參考:https://blog.csdn.net/huangliniqng/article/details/88554510
? ? ? 概念:反射就是把java類中的各種成分映射成一個(gè)個(gè)的Java對(duì)象。
? ? ? Java的反射機(jī)制是Java特性之一,反射機(jī)制是構(gòu)建框架技術(shù)的基礎(chǔ)所在。
? ? ? 反射機(jī)制:在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語(yǔ)言的反射機(jī)制。
? ? ? 使用條件:必須先得到代表的字節(jié)碼的Class,Class類用于表示.class文件(字節(jié)碼)
? ? (要想解剖一個(gè)類,必須先要獲取到該類的字節(jié)碼文件對(duì)象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個(gè)字節(jié)碼文件對(duì)應(yīng)的Class類型的對(duì)象.)
? ?
? ?定義:JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意方法和屬性;這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為java語(yǔ)言的反射機(jī)制。
? ?鏈接詳解:https://blog.csdn.net/misswwg/article/details/51659812
? ?那么什么是Java的反射呢?
? ? ? 要讓Java程序能夠運(yùn)行,那么就得讓Java類要被Java虛擬機(jī)加載。Java類如果不被Java虛擬機(jī)加載,是不能正常運(yùn)行的。現(xiàn)在我們運(yùn)行的所有的程序都是在編譯期的時(shí)候就已經(jīng)知道了你所需要的那個(gè)類的已經(jīng)被加載了。
? ? ? Java的反射機(jī)制是在編譯并不確定是哪個(gè)類被加載了,而是在程序運(yùn)行的時(shí)候才加載、探知、自審。使用在編譯期并不知道的類。這樣的特點(diǎn)就是反射。
? ?那么Java反射有什么作用呢?
? ? ? 假如我們有兩個(gè)程序員,一個(gè)程序員在寫程序的時(shí)候,需要使用第二個(gè)程序員所寫的類,但第二個(gè)程序員并沒(méi)完成他所寫的類。那么第一個(gè)程序員的代碼能否通過(guò)編譯呢?這是不能通過(guò)編譯的。利用Java反射的機(jī)制,就可以讓第一個(gè)程序員在沒(méi)有得到第二個(gè)程序員所寫的類的時(shí)候,來(lái)完成自身代碼的編譯。
? ? ? Java的反射機(jī)制它知道類的基本結(jié)構(gòu),這種對(duì)Java類結(jié)構(gòu)探知的能力,我們稱為Java類的“自審”。大家都用過(guò)Jcreator和eclipse。當(dāng)我們構(gòu)建出一個(gè)對(duì)象的時(shí)候,去調(diào)用該對(duì)象的方法和屬性的時(shí)候。一按點(diǎn),編譯工具就會(huì)自動(dòng)的把該對(duì)象能夠使用的所有的方法和屬性全部都列出來(lái),供用戶進(jìn)行選擇。這就是利用了Java反射的原理,是對(duì)我們創(chuàng)建對(duì)象的探知、自審。
? ?Class類
? ? ? 要正確使用Java反射機(jī)制就得使用java.lang.Class這個(gè)類。它是Java反射機(jī)制的起源。當(dāng)一個(gè)類被加載以后,Java虛擬機(jī)就會(huì)自動(dòng)產(chǎn)生一個(gè)Class對(duì)象。通過(guò)這個(gè)Class對(duì)象我們就能獲得加載到虛擬機(jī)當(dāng)中這個(gè)Class對(duì)象對(duì)應(yīng)的方法、成員以及構(gòu)造方法的聲明和定義等信息。
? ?反射API
? ? ? u反射API用于反應(yīng)在當(dāng)前Java虛擬機(jī)中的類、接口或者對(duì)象信息
? ? ? u功能
? ? ? —獲取一個(gè)對(duì)象的類信息.
? ? ? —獲取一個(gè)類的訪問(wèn)修飾符、成員、方法、構(gòu)造方法以及超類的信息.
? ? ? —檢獲屬于一個(gè)接口的常量和方法聲明.
? ? ? —?jiǎng)?chuàng)建一個(gè)直到程序運(yùn)行期間才知道名字的類的實(shí)例.
? ? ? —獲取并設(shè)置一個(gè)對(duì)象的成員,甚至這個(gè)成員的名字是在程序運(yùn)行期間才知道.
? ? ? —檢測(cè)一個(gè)在運(yùn)行期間才知道名字的對(duì)象的方法
? ? ? ..........
? ?反射機(jī)制是框架技術(shù)的原理和核心部分。通過(guò)反射機(jī)制我們可以動(dòng)態(tài)的通過(guò)改變配置文件(以后是XML文件)的方式來(lái)加載類、調(diào)用類方法,以及使用類屬性。這樣的話,對(duì)于編碼和維護(hù)帶來(lái)相當(dāng)大的便利。在程序進(jìn)行改動(dòng)的時(shí)候,也只會(huì)改動(dòng)相應(yīng)的功能就行了,調(diào)用的方法是不用改的。更不會(huì)一改就改全身。
? ?.反射 ?
??????????① 反射機(jī)制 :指在運(yùn)行狀態(tài)中,對(duì)任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)任意一個(gè)對(duì)象,都能夠調(diào)用它的一個(gè)方法;這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為java語(yǔ)言的反射機(jī)制。
??????????② 反射API :java通常是先有類再有對(duì)象,有對(duì)象我就可以調(diào)用方法或者屬性。反射其實(shí)是通過(guò)Class對(duì)象來(lái)調(diào)用類里面的方法。通過(guò)反射可以調(diào)用私有方法和私有屬性。大部分框架都是運(yùn)用反射原理
???????????????Class類 :獲取到類的屬性、方法等信息
???????????????Field類 ??:表示類的屬性,通過(guò)它獲取和設(shè)置類中屬性的值
???????????????Method類 ?: 表示類的方法,用來(lái)獲取類中方法的信息,或者執(zhí)行方法
???????????????Constructor類 ?:表示類的構(gòu)造方法, 通過(guò)它可以動(dòng)態(tài)的創(chuàng)建對(duì)象
?
總結(jié)
以上是生活随笔為你收集整理的2020-10-23 集合+序列化+递归+多线程+泛型+枚举+单例+反射小记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux内核不能识别u盘分区,一种在L
- 下一篇: UNI-APP安卓本地打包详细教程(保姆