日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2020-10-23 集合+序列化+递归+多线程+泛型+枚举+单例+反射小记

發布時間:2024/3/13 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2020-10-23 集合+序列化+递归+多线程+泛型+枚举+单例+反射小记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【集合】:

Collection接口

(Collection接口是集合類的根接口,Java中沒有提供這個接口的直接的實現類。但是卻讓其被繼承產生了兩個接口,就是Set和List)

Set接口(無序集合,不允許重復,檢索元素效率低下,刪除和插入效率高,插入和刪除不會引起元素位置改變)

HashSet(以哈希表的形式存放元素,插入刪除速度很快)

LinkedHashSet(有序集合)

SortedSet

TreeSet(排序集合)

EnumSet

?

Queue(隊列)

...

?

...

?

List接口(有序集合,可以有重復元素,提供了按索引訪問的方式。和數組類似,List可以動態增長,查找元素效率高,插入刪除元素效率低,因為會引起其他元素位置改變)

Vector(線程安全的,但是效率低)

Stack(線程安全的,但是效率低;是Vector的一個子類,它實現了標準的后進先出堆棧)

線程不安全的類都可以配合Collections得到線程安全的類

ArrayList(動態數組)

?

LinkedList(鏈表、隊列、堆棧)

?

Map(無序集合)

HashMap (Key不允許重復;快速訪問,取得數據的順序隨機,非同步)

LinkedHashMap(有序集合,比HashMap慢,保存了記錄的插入順序,遍歷時先得到的記錄肯定是先插入的,有HashMap的全部特性)

Hashtable(Key不允許重復;是HashMap的線程安全版,支持線程的同步,即同一時刻只有一個線程能寫Hashtable,效率低)

ConcurrentHashMap線程安全且鎖分離

Properties (Properties是Hashtable的子類。它用于維護鍵的列表,其中鍵是String,值也是String。)

SortedMap

TreeMap(排序集合,默認是按鍵值的升序排序,非同步;實現SortedMap接口,能把保存的記錄根據鍵排序)

WeakHashMap

?

IdentityHashMap

?

EnumMap

?

?

//Set集合(遍歷方式:迭代器迭代/forEach循環遍歷,與list方式一樣):Set set = new HashSet();set.add("Bernadine");set.add("Clara"); /*set接口中不能加入重復元素,但是可以排序--HashSet散列存放;TreeSet排序集合*/Set set= new TreeSet(set); //排序集合:根據內容自動排序(不是按照插入順序) // List集合: /*ArrayList和Vector比較:ArrayList采用異步處理的方式,性能高,屬于非線程安全;Vector采用同步處理的方式,性能低,屬于線程安全。*/ /*ArrayList和LinkedList在用法上沒有區別,但是在功能上還是有區別的。LinkedList經常用在增刪操作較多而查詢操作很少的情況下,ArrayList則相反。*/List list = new Vector(); //java.util.Vector;List<Object> list=new ArrayList<Object>(); // java.util.ArrayList; --使用泛型指定類型為 Object(不使用泛型:List list=new ArrayList();)list.add(“***”); //寫入數據list.remove(0); //刪除當前元素list.indexOf("a"); //查找制定的對象是否存在(返回int)list.isEmpty(); //判斷集合是否為空(返回booole)/*遍歷list集合-1(使用迭代器迭代),Iterator是專門的迭代輸出接口,迭代輸出就是將元素一個個進行判斷,判斷其是否有內容,如果有則把內容取走*/Iterator<User> it=list.iterator(); //不能在迭代輸出的時候進行iter.remove()刪除操作,會報錯while (it.hasNext()) { //使用hasNext()檢查序列中是否還有元素(判斷是否下一個元素為空)User user1 = (User) it.next(); // 使用next()獲得序列中的下一個元素System.out.println("username:"+user1.getUsername());}/*遍歷list集合-2 (forEach循環遍歷)*/for (String s : list) { System.out.println(s);}/*遍歷list集合-3 (for循環遍歷)*/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元素作為參數,如果該元素在map中映射,則返回Truemap.put(users.getUsername(), users); //寫入數據map.put("1", 1);int i = (int) map.get("1"); //提取鍵值map.containsKey("1"); //看key是不是存在 返回booleanmap.containsValue(1); //看value是不是存在,返回boolean/*遍歷map集合-1 (map無法直接使用Iterator遍歷,需要先獲取set視圖)*/Set<String> set=map.keySet(); //第一種:map.keySet()可以將所有的鍵都提取出來,返回的是一個Set集合Iterator<String> it=set.iterator(); //使用set集合調用迭代器Iterator來進行輸出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循環遍歷HashMap的entrySetSystem.out.println("key:"+entry.getKey()+"? value:"+entry.getValue());}/*遍歷map集合-3(只取到value) */for (String s : map.values()) { //map.values();是返回所有值,返回是一個Collection 集合System.out.println(s);}

【序列化】:
? ?IO流示例:CSDN博客?https://blog.csdn.net/qq_36095102/article/details/99735418
? ?字符流和字節流區別:
? ? ? //字符流處理的單元為2個字節的Unicode字符,分別操作字符、字符數組或字符串,而字節流處理單元為1個字節,操作字節和字節數組;
? ? ? //讀文本的時候用字符流,例如txt文件,讀非文本文件的時候用字節流,例如mp3;
? ? ? //字節流提供了處理任何類型的IO操作的功能,但不能直接處理Unicode字符,而字符流就可以。
? ?緩沖流原理:
? ? ? 1)緩沖區的出現:提高了流的讀寫效率,所以在緩沖區創建前,要先創建流對象。即先將流對象初始化到構造函數中。
? ? ? 2)緩沖技術原理:此對象中封裝了數組,將數據存入,再一次性取出。
? ? ? 3)寫入流緩沖區BufferedWriter?
? ?序列化和反序列化:
? ? ? ?// 將程序中的對象寫入文件,之后再從文件中把對象讀出來重新建立,這就是所謂的對象序列化。Java中引入它主要是為了RMI(Remote Method Invocation)和Java Bean所用。
? ? ? ?/*Externalizable接口繼承自 Serializable接口,實現Externalizable接口的類完全由自身來控制序列化的行為,而僅實現Serializable接口的類可以采用默認的序列化方式 */?
? ? ? ?/*只有實現了Serializable和Externalizable接口的類的對象才能被序列化。 */
? ? ? ?/*序列化(Serialization):是將對象的狀態信息轉換為可以存儲或傳輸的形式的過程;序列化時,對象將其當前狀態寫入到臨時或持久性存儲區;可以通過從存儲區中讀取或反序列化對象的狀態,重新創建該對象。*/

transient int k = 15; ? //實現Serilizable接口時,將不需要序列化的屬性前添加關鍵字transient,序列化對象的時候,該屬性就不會序列化到指定的目的地中/*讀取(反序列化):把字節序列恢復為對象的過程稱為對象的反序列化*/FileInputStream fis=new FileInputStream(new File("C:/test.text")); //創建一個對象輸入流ObjectInputStream ois=new ObjectInputStream(fis);Object obj=ois.readObject(); //通過對象輸入流readObject()方法讀取數據System.out.println(obj);/*寫入(序列化):將對象狀態轉換為可保持或傳輸格式的過程*/FileOutputStream fos=new FileOutputStream(new File("C:/test.text"));ObjectOutputStream oos=new ObjectOutputStream(fos); //創建一個對象輸出流oos.writeObject("***"); //過對象輸出流的writeObject( )方法寫對象oos.flush();

【遞歸 (Recursion)?】:
? ?//使用范圍:當一個功能被重復使用,而每一次使用該功能時的參數不確定,都由上次的功能元素結果來確定。其實遞歸就是在棧內存中不斷的加載同一個函數。

//1.輸出指定路徑下的所有文件和文件夾public static void showDir(File file){System.out.println(file); //打印目錄File[] files=file.listFiles();for(int i=0;i<files.length;i++){if(files[i].isDirectory()){ //判斷是否是目錄(文件夾)showDir(files[i]); //遞歸}else{System.out.println(files[i]); //打印指定路徑下的所有文件名稱}}}//2.遞歸運算,以二進制方法為例public static void toBin(int num){if(num>0){toBin(num/2); //遞歸System.out.println(num+":"+num%2); //兩數相除后的余數(會先打印最后的結果,然后倒序輸出!)}}//3.求和運算public static int getSum(int n){if(n==1){return n;}else{return n+getSum(n-1);}}

【多線程 (Multi Thread)?】:
? ? ? 多線程定義:指的是這個程序(一個進程)運行時產生了不止一個線程(一個進程在其執行過程中可以產生多個線程)
? ? ? 進程:是程序的一次動態執行過程
? ? ? 線程:是進程中執行運算的最小單位,一個進程在其執行過程中可以產生多個線程,而線程必須在某個進程內執行。
? ? ? 多線程:線程是進程內部的一個執行單元,可完成一個獨立的任務的順序控制流程,如果在一個進程中同時運行了多個線程,用來完成不同的工作,則稱之為多線程。
? ? ? 并行:多個cpu實例或者多臺機器同時執行一段處理邏輯,是真正的同時。
? ? ? 并發:通過cpu調度算法,讓用戶看上去同時執行,實際上從cpu操作層面不是真正的同時。并發往往在場景中有公用的資源,那么針對這個公用的資源往往產生瓶頸,我們會用TPS或者QPS來反應這個系統的處理能力。
? ? ? 線程安全:經常用來描繪一段代碼。指在并發的情況之下,該代碼經過多線程使用,線程的調度順序不影響任何結果。這個時候使用多線程,我們只需要關注系統的內存,cpu是不是夠用即可。反過來,線程不安全就意味著線程的調度順序會影響最終結果
? ? ? 同步:Java中的同步指的是通過人為的控制和調度,保證共享資源的多線程訪問成為線程安全,來保證結果的準確。
? ? ? 目的:就是"最大限度地利用CPU資源",當某一線程的處理不需要占用CPU而只和I/O,OEMBIOS等資源打交道時,讓需要占用CPU資源的其它線程有機會獲得CPU資源。從根本上說,這就是多線程編程的最終目的。要通過不斷切換需要運行的線程讓其運行的方式就叫并發(concurrent)。而在多CPU系統中,可以讓兩個以上的線程同時運行,這種可以同時讓兩個以上線程同時運行的方式叫做并行(parallel)。

? ? ? 線程完整的生命周期:
? ? ?? ? ? 新建狀態: 一個新產生的線程從新狀態開始了它的生命周期。它保持這個狀態直到程序start這個線程。
? ? ?? ? ? 運行狀態:當一個新狀態的線程被start以后,線程就變成可運行狀態,一個線程在此狀態下被認為是開始執行其任務
? ? ? ? ? ?就緒狀態:當一個線程等待另外一個線程執行一個任務的時候,該線程就進入就緒狀態。當另一個線程給就緒狀態的線程發送信號時,該線程才重新切換到運行狀態。
? ? ? ? ? ?休眠狀態: 由于一個線程的時間片用完了,該線程從運行狀態進入休眠狀態。當時間間隔到期或者等待的事件發生了,該狀態的線程切換到運行狀態。
? ? ?? ? ? 終止狀態: 一個運行狀態的線程完成任務或者其他終止條件發生,該線程就切換到終止狀態。

? ? ? 多線程三種實現方法:
? ? ?? ? ? 1)繼承Thread類,重寫run()方法
? ? ? ? ? ? 2)實現Runnable接口,并實現該接口的run()方法
? ? ? ? ? ? 3)使用ExecutorService、Callable、Future實現有返回結果的多線程(實現Callable接口,重寫call()方法)
? ? ? ? ? ? 其中前兩種方式線程執行完后都沒有返回值,只有最后一種是帶返回值的。run()方法可以產生必須退出的標志來停止一個線程.??
? ? ? 同步的實現方面有兩種:
? ? ? ? ? ? synchronized、wait與notify

? ? ? 繼承Thread類的方法盡管被我列為一種多線程實現方式,但Thread本質上也是實現了Runnable接口的一個實例,它代表一個線程的實例,并且,啟動線程的唯一方法就是通過Thread類的start()實例方法。start()方法是一個native方法,它將啟動一個新線程,并執行run()方法。這種方式實現多線程很簡單,通過自己的類直接extend Thread,并復寫run()方法,就可以啟動新線程并執行自己定義的run()方法。例如:

//繼承Thread類,重寫run()方法 public class MyThread extends Thread { ?public void run() { ?System.out.println("MyThread.run()"); ?} ? } ?//在合適的地方啟動線程如下:MyThread myThread1 = new MyThread(); ?MyThread myThread2 = new MyThread(); ?myThread1.start(); ?myThread2.start(); ?

? ? ? 設計4個線程:其中兩個線程每次對j增加1,另外兩個線程對j每次減少1。寫出程序。
? ? ? 以下程序使用內部類實現線程,對j增減的時候沒有考慮順序問題。

public class ThreadTest1{private int j;?public static void main(String args[]){?ThreadTest1 tt=new ThreadTest1();?Inc inc=tt.new Inc();Dec dec=tt.new Dec();for(int i=0;i<2;i++){?Thread t=new Thread(inc);?t.start();t=new Thread(dec);?t.start();?}}?private synchronized void inc(){?j++;?System.out.println(Thread.currentThread().getName()+"-inc:"+j);?}private synchronized void dec(){j--;?System.out.println(Thread.currentThread().getName()+"-dec:"+j);?}//2.實現Runnable接口,并實現該接口的run()方法class Inc implements Runnable{?public void run(){?for(int i=0;i<100;i++){? inc();? }}?}class Dec implements Runnable{public void run(){?for(int i=0;i<100;i++){ dec(); }}?}?}

【泛型 (Generics)?】:

泛型定義:
? ? ? 本質是參數化類型,當類中操作的引用類型不確定時引用 (這樣可以避免強轉的麻煩,而且將運行問題轉移到的編譯時期)
? ? ? //也就是說操作的數據類型被指定為一個參數,使代碼可以應用于多種類型
? ? ? //將對象的類型作為參數,指定到其他類或者方法上,從而保證類型轉換的安全性和穩定性,這就是泛型。
語法:
? ? ? 類1或者接口<類型實參> 對象=new 類2<類型實參>( );
??????例:List<NewTitle> list=new ArrayList<NewTitle>( );

//1.定義泛型類的語法:訪問修飾符 class className<TypeList> ? //--TypeList:表示類型參數列表 public class GenericClass<T>{......} //創建泛型類實例的語法:new className<TypeList>(argList); ? //--TypeList:表示定義的類型參數列表 , argList : 表示實際傳遞的類型參數列表 GenericClass<String> genc = new GenericClass<String>("this is String object") //繼承泛型類的語法:訪問修飾符 class 子類<T> extends 父類<T>{ } public class 子類<T> extends GenericClass<T>{ }//2.定義泛型接口的語法:訪問修飾符 interface interfaceName<TypeList> ?----TypeList:表示由逗號分隔的一個或多個類型參數列表 public interface TestInterface<T>{public T print(T t); } //泛型類實現泛型接口的語法:訪問修飾符 class className<TypeList> inplements interfaceName<TypeList> public class className<TypeList> inplements interfaceName<TypeList>//3.定義泛型方法的語法:訪問修飾符 <類型參數> 返回值 方法名(類型參數列表) public <String> void showName(String s){ } ? //注意:泛型方法中,類型變量是放置在訪問修飾符與返回值之間 public static <String> void showName(String s){ }

【枚舉(enum)】:

定義:指由一組固定的常量組成的類型(使用關鍵字enum定義,繼承java.lang.Enum)
? ? ? ? ? ?Enum 一般用來表示一組相同類型的常量

//枚舉定義語法:[訪問修飾符] enum enumName{?? ? //enum是關鍵字(類似于class關鍵字)enum1, enum2;?? ?//枚舉常量列表,枚舉常量之間以逗號隔開(枚舉中,如果除了定義枚舉常量,還定義了其他成員,則枚舉常量列表必須以分號(;)結尾)?? ?[field , method] //表示其他的成員,包括構造方法,置于枚舉常量的后面} //不使用枚舉時: public class Direction {public static final int EAST = 0;public static final int WEST = 1;public static final int SOUTH = 2;public static final int NORTH = 3; }/* 用法一:常量 */public enum DirectionEnum {EAST, WEST, NORTH, SOUTH}/* 用法二:switch (JDK1.6之前的switch語句只支持int,char,enum類型)*/public enum Signal {GREEN, YELLOW, RED}public class TrafficLight {Signal color = Signal.RED; public void change() { switch (color) { case RED: color = Signal.GREEN; break; case YELLOW: color = Signal.RED; break; case GREEN: color = Signal.YELLOW; break; } } } //用法三:自定義方法(必須在enum實例序列的最后添加一個分號,而且Java要求必須先定義enum實例)public enum Color{RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);// 成員變量private String name;private int index;// 構造方法private Color(String name, int index) {this.name = name;this.index = index;}/* 1.向枚舉中添加新方法 */public static String getName(int index) {for (Color c : Color.values()) {//......}return null;}/* 2.覆蓋枚舉的方法 */@Overridepublic String toString() { return this.index + "_" + this.name;}}//用法三調用public static void main(String[] args){System.out.println(Color.RED.toString());}

【單例模式 (SingletonPattern) 】:
? ? ? 參考: https://www.runoob.com/design-pattern/singleton-pattern.html
? ? ? 單例模式:常見23種設計模式之單例模式。
? ? ? 3個特點:
  ?? ?①、單例類只能有一個實例。
  ?? ?②、單例類必須自己創建自己的唯一實例。
  ?? ?③、單例類必須給所有其他對象提供這一實例。
? ? ? ?? ?(構造函數是私有的,方法是static的)
??????定義:一個類有且僅有一個實例,并且自行實例化向整個系統提供。
??????目的:是保證整個應用中只存在類的唯一個實例。
? ? ? ? ? ? ? ? ?比如我們在系統啟動時,需要加載一些公共的配置信息,對整個應用程序的整個生命周期中都可見且唯一,這時需要設計成單例模式。如:spring容器,session工廠,緩存,數據庫連接池等等。
??????優點:該類只存在一個實例,節省系統資源;對于需要頻繁創建銷毀的對象,使用單例模式可以提高系統性能。
??????缺點:不能外部實例化(new),調用人員不清楚調用哪個方法獲取實例時會感到迷惑,尤其當看不到源代碼時。
??????意圖:保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。
??????主要解決:一個全局使用的類頻繁地創建與銷毀。
??????何時使用:當您想控制實例數目,節省系統資源的時候。
? ? ? 意義:單例模式確保某個類只有一個實例,而且自行實例化并向整個系統提供這個實例。在計算機系統中,線程池、緩存、日志對象、對話框、打印機、顯卡的驅動程序對象常被設計成單例。這些應用都或多或少具有資源管理器的功能。每臺計算機可以有若干個打印機,但只能有一個Printer Spooler,以避免兩個打印作業同時輸出到打印機中。每臺計算機可以有若干通信端口,系統應當集中管理這些通信端口,以避免一個通信端口同時被兩個請求同時調用。總之,選擇單例模式就是為了避免不一致狀態,避免政出多頭。
? ? ? 分類:
? ? ? ? ? ? 懶漢式單例(實現線程安全三種方式:在getInstance方法上加同步、雙重檢查鎖定、靜態內部類)
? ? ? ? ? ? 餓漢式單例
? ? ? ? ? ? 登記式單例(可忽略)
? ? ? ? ? ?( 始終是一個對象實例.它對外不提供構造函數,因此我們不能夠同時產生多個對象. )
? ? ? ? ? ?參考:https://blog.csdn.net/emira_j/article/details/52447390
? ? ? 應用實例:Windows 是多進程多線程的,在操作一個文件的時候,就不可避免地出現多個進程或線程同時操作一個文件的現象,所以所有文件的處理必須通過唯一的實例來進行。

public class SingleObject {//創建 SingleObject 的一個對象private static SingleObject instance = new SingleObject();//讓構造函數為 private,這樣該類就不會被實例化private SingleObject(){}//獲取唯一可用的對象public static SingleObject getInstance(){return instance;}public void showMessage(){System.out.println("Hello World!");} }//從 singleton 類獲取唯一的對象: public class SingletonPatternDemo {public static void main(String[] args) {//不合法的構造函數//編譯時錯誤:構造函數 SingleObject() 是不可見的//SingleObject object = new SingleObject();//獲取唯一可用的對象SingleObject object = SingleObject.getInstance();//顯示消息object.showMessage();} } //單例模式的幾種實現方式://懶漢式—線程不安全(懶漢式單例開始沒有實例化對象,用到時才實例化,比較節省空間)//懶漢式—線程安全(+synchronized 修飾符)//餓漢方式//雙檢鎖式//登記式//枚舉

你用杯子喝可樂,喝完了不刷,繼續去倒果汁喝,就是單例。
你用杯子喝可樂,直接扔了杯子,換個杯子去倒果汁喝,就是多例。
①. 什么是單例多例:
?? ?所謂單例就是所有的請求都用一個對象來處理,比如我們常用的service和dao層的對象通常都是單例的,而多例則指每個請求用一個新的對象來處理,比如action;
②. 如何產生單例多例:
?? ?在通用的SSH中,單例在spring中是默認的,如果要產生多例,則在配置文件的bean中添加scope="prototype";
③. 為什么用單例多例:
?? ?之所以用單例,是因為沒必要每個請求都新建一個對象,這樣子既浪費CPU又浪費內存;
?? ?之所以用多例,是為了防止并發問題;即一個請求改變了對象的狀態,此時對象又處理另一個請求,而之前請求對對象狀態的改變導致了對象對另一個請求做了錯誤的處理;
?? ?用單例和多例的標準只有一個:
?????? ?當對象含有可改變的狀態時(更精確的說就是在實際應用中該狀態會改變),則多例,否則單例;
④. 何時用單例?何時用多例?
?? ?對于struts2來說,action必須用多例,因為action本身含有請求參數的值,即可改變的狀態;
?? ?而對于STRUTS1來說,action則可用單例,因為請求參數的值是放在actionForm中,而非action中的;
?? ?另外要說一下,并不是說service或dao一定是單例,標準同第3點所講的,就曾見過有的service中也包含了可改變的狀態,同時執行方法也依賴該狀態,但一樣用的單例,這樣就會出現隱藏的BUG,而并發的BUG通常很難重現和查找;

/懶漢式單例類.在第一次調用的時候實例化自己 public class Singleton {??private static Singleton single=null;???????private Singleton() {}??? ?//靜態工廠方法???public static Singleton getInstance() {??if (single == null) { ?synchronized(Singleton.class){single = new Singleton();??}}????return single;??}?? }?

【反射 (Reflection)?】:
? ? ? 參考:https://blog.csdn.net/huangliniqng/article/details/88554510
? ? ? 概念:反射就是把java類中的各種成分映射成一個個的Java對象。
? ? ? Java的反射機制是Java特性之一,反射機制是構建框架技術的基礎所在。
? ? ? 反射機制:在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
? ? ? 使用條件:必須先得到代表的字節碼的Class,Class類用于表示.class文件(字節碼)
? ? (要想解剖一個類,必須先要獲取到該類的字節碼文件對象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個字節碼文件對應的Class類型的對象.)

public static void main(String[] args) {try {Class cl=Class.forName("com.cn.yx.reflect.ReflectBook"); //1.1 獲取類名clReflectBook rbook=new ReflectBook(); //1.2 獲取類名clClass cl2=rbook.getClass();Constructor[] constructors=cl.getDeclaredConstructors(); //2.1通過getDeclaredConstructors可以返回類的所有構造方法,返回一個數組...for (int i = 0; i < constructors.length; i++) {System.out.print(Modifier.toString(constructors[i].getModifiers())+ "\t參數:"); //通過getModifiers可以得到構造方法的類型publicClass[] parametertypes=constructors[i].getParameterTypes(); //getParameterTypes可以得到構造方法的所有參數,返回的是一個Class數組for (int j = 0; j < parametertypes.length; j++) {System.out.print(parametertypes[j].getName()+"\t");}System.out.println(constructors[i]); //打印構造方法}//2.2也可以通過getConstructors方法獲取類中 所有的public類型的構造方法(與上面獲取方法一樣)......//得到類的實例,主要借助于newInstance方法Class[] p={int.class,String.class};Constructor constructor=cl.getDeclaredConstructor(p); //2.3或者通過getDeclaredConstructor()方法傳參獲取特定參數類型的構造方法,返回的是一個Class對象... // constructor.setAccessible(true); //調用私有構造方法加這個即可constructor.newInstance(26,"楊旭"); //調用有兩個參數的構造方法//3.通過 getDeclaredMethod方法獲取到這個私有方法,第一個參數是方法名,第二個參數是參數類型Class[] p4 = {String.class};Method method=cl.getDeclaredMethod("welcome", p4); //獲得私有方法welcome()method.setAccessible(true);Object arg1s[]={"歡迎關注!!!"};method.invoke(rbook, arg1s); //過invoke方法執行,invoke需要兩個參數一個是類的實例,一個是方法參數//4.通過反射得到類的實例之后先獲取字段Field field = cl.getDeclaredField("name");field.setAccessible(true);field.set(rbook,"代碼"); System.out.println("打印name值為:"+field.get(rbook).toString());} catch (ClassNotFoundException e) {e.printStackTrace();} catch...}

? ?

? ?定義:JAVA反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱為java語言的反射機制。
? ?鏈接詳解:https://blog.csdn.net/misswwg/article/details/51659812
? ?那么什么是Java的反射呢?
? ? ? 要讓Java程序能夠運行,那么就得讓Java類要被Java虛擬機加載。Java類如果不被Java虛擬機加載,是不能正常運行的。現在我們運行的所有的程序都是在編譯期的時候就已經知道了你所需要的那個類的已經被加載了。
? ? ? Java的反射機制是在編譯并不確定是哪個類被加載了,而是在程序運行的時候才加載、探知、自審。使用在編譯期并不知道的類。這樣的特點就是反射。
? ?那么Java反射有什么作用呢?
? ? ? 假如我們有兩個程序員,一個程序員在寫程序的時候,需要使用第二個程序員所寫的類,但第二個程序員并沒完成他所寫的類。那么第一個程序員的代碼能否通過編譯呢?這是不能通過編譯的。利用Java反射的機制,就可以讓第一個程序員在沒有得到第二個程序員所寫的類的時候,來完成自身代碼的編譯。
? ? ? Java的反射機制它知道類的基本結構,這種對Java類結構探知的能力,我們稱為Java類的“自審”。大家都用過Jcreator和eclipse。當我們構建出一個對象的時候,去調用該對象的方法和屬性的時候。一按點,編譯工具就會自動的把該對象能夠使用的所有的方法和屬性全部都列出來,供用戶進行選擇。這就是利用了Java反射的原理,是對我們創建對象的探知、自審。
? ?Class類
? ? ? 要正確使用Java反射機制就得使用java.lang.Class這個類。它是Java反射機制的起源。當一個類被加載以后,Java虛擬機就會自動產生一個Class對象。通過這個Class對象我們就能獲得加載到虛擬機當中這個Class對象對應的方法、成員以及構造方法的聲明和定義等信息。
? ?反射API
? ? ? u反射API用于反應在當前Java虛擬機中的類、接口或者對象信息
? ? ? u功能
? ? ? —獲取一個對象的類信息.
? ? ? —獲取一個類的訪問修飾符、成員、方法、構造方法以及超類的信息.
? ? ? —檢獲屬于一個接口的常量和方法聲明.
? ? ? —創建一個直到程序運行期間才知道名字的類的實例.
? ? ? —獲取并設置一個對象的成員,甚至這個成員的名字是在程序運行期間才知道.
? ? ? —檢測一個在運行期間才知道名字的對象的方法
? ? ? ..........
? ?反射機制是框架技術的原理和核心部分。通過反射機制我們可以動態的通過改變配置文件(以后是XML文件)的方式來加載類、調用類方法,以及使用類屬性。這樣的話,對于編碼和維護帶來相當大的便利。在程序進行改動的時候,也只會改動相應的功能就行了,調用的方法是不用改的。更不會一改就改全身。
? ?.反射 ?
??????????① 反射機制 :指在運行狀態中,對任意一個類,都能夠知道這個類的所有屬性和方法;對任意一個對象,都能夠調用它的一個方法;這種動態獲取信息以及動態調用對象方法的功能稱為java語言的反射機制。
??????????② 反射API :java通常是先有類再有對象,有對象我就可以調用方法或者屬性。反射其實是通過Class對象來調用類里面的方法。通過反射可以調用私有方法和私有屬性。大部分框架都是運用反射原理
???????????????Class類 :獲取到類的屬性、方法等信息
???????????????Field類 ??:表示類的屬性,通過它獲取和設置類中屬性的值
???????????????Method類 ?: 表示類的方法,用來獲取類中方法的信息,或者執行方法
???????????????Constructor類 ?:表示類的構造方法, 通過它可以動態的創建對象

package Reflect;? ? ? ?? /*** 通過一個對象獲得完整的包名和類名* */? class Demo{?//other codes...? }?class hello{?public static void main(String[] args) {?Demo demo=new Demo();?System.out.println(demo.getClass().getName());?}? } ?// 【運行結果】:Reflect.Demo?

?

總結

以上是生活随笔為你收集整理的2020-10-23 集合+序列化+递归+多线程+泛型+枚举+单例+反射小记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。