PHP 獲取一年所有周開始時間結束時間
歡迎訪問博主個人網站,記得收藏哦,點選檢視 - - - >>>>
原文連結:原文來自公眾號:C you again,歡迎關注!
1、問題描述
“如何在Integer型別的ArrayList中同時新增String、Character、Boolean等型別的資料?”
你是不是想到下面的程式碼?
package com.cya.test; import java.util.ArrayList; import java.util.List; public class Test{ public static void main(String []args){ List<Integer> list=new ArrayList<>(); Integer in=1; Character ch='c'; Boolean bo=true; list.add(in); list.add(ch); list.add(bo); System.out.println(list); } }
有點Java基礎的人都知道上面的程式碼執行會報錯,如果使用Eclipse等開發工具的話在沒執行之前就會提示有錯了,如下圖:
強制執行一波,看下錯誤提示:
Exception in thread "main" java.lang.Error: Unresolved compilation problems: The method add(Integer) in the type List<Integer> is not applicable for the arguments (Character) The method add(Integer) in the type List<Integer> is not applicable for the arguments (Boolean) at com.cya.test.Test.main(Test.java:15)
聽說英語差的都去當程式設計師了!!
不過沒關係,能get到大體意思就好了,上面的錯誤大體意思如下:
程式在編譯時遇到了無法解析的錯誤,
add方法的引數是Integer型別,無法接收Character型別的引數,
add方法的引數是Integer型別,無法接收Boolean型別的引數
上面程式碼錯誤的原因是程式無法通過編譯,在編譯期出現異常,這和Java是編譯性語言(如:C、C++、Delphi、Pascal、Java)有關。與解釋性語言(如:Basic、javascript、Python)不同,Java先將字尾名為.java的原始碼檔案編譯成字尾名為.class的位元組碼檔案,編譯期間會進行詞法、語法、資料型別、語義分析。上面的錯誤就是在編譯期間進行資料型別分析時型別不匹配造成的。
談到這裡,我們不得不提下Java的異常體系,異常體系結構圖如下:
2、什麼是異常
程式在執行過程中發生由於硬體裝置問題、軟體設計錯誤等導致的程式異常事件。(在Java等面向物件的程式語言中)異常本身是一個物件,產生異常就是產生了一個異常物件。
3、異常體系分類
如上面的Java異常體系結構圖所示,Throwable有兩個重要的子類:Exception(異常)和Error(錯誤),兩者都包含了大量的異常處理類。
(一)Error(錯誤)
程式中無法處理的錯誤,表示執行應用程式中出現了嚴重的錯誤。此類錯誤一般表示程式碼執行時JVM出現問題。通常有Virtual MachineError(虛擬機器執行錯誤)、NoClassDefFoundError(類定義錯誤)等。比如說當JVM耗完可用記憶體時,將出現OutOfMemoryError。此類錯誤發生時,JVM將終止執行緒。
這些錯誤是不可查的,非程式碼性錯誤。因此,當此類錯誤發生時,應用不應該去處理此類錯誤。
(二)Exception(異常)
程式本身可以捕獲並且可以處理的異常。
Exception這種異常又分為兩類:執行時異常和編譯異常。
-
執行時異常(不受檢異常):RuntimeException類及其子類表示JVM在執行期間可能出現的錯誤。比如說試圖使用空值物件的引用(NullPointerException)、陣列下標越界(ArrayIndexOutBoundException)。此類異常屬於不可查異常,一般是由程式邏輯錯誤引起的,在程式中可以選擇捕獲處理,也可以不處理。
-
編譯異常(受檢異常):Exception中除RuntimeException及其子類之外的異常。如果程式中出現此類異常,比如說IOException,必須對該異常進行處理,否則編譯不通過。在程式中,通常不會自定義該類異常,而是直接使用系統提供的異常類。
看完了Java的異常體系,我們知道上面程式碼出現的異常為編譯時異常,是必須要處理的,否則無法通過編譯階段,更不要談運行了。
既然上面程式碼不可用,那就請出本期的主角---Java的反射機制。
4、反射的概述
JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取資訊以及動態呼叫物件方法的功能稱為Java語言的反射機制。
5、反射機制的作用
在執行時判斷任意一個物件所屬的類;
在執行時構造任意一個類的物件;
在執行時判斷任意一個類所具有的成員變數和方法;
在執行時呼叫任意一個物件的方法;
6、反射的三種實現方式
- 通過物件的getClass()方法。getClass()方法是Object類的方法,因為所有類都繼承自Object類,所以可以直接使用getClass()方法。
- 通過類名.class屬性。如果知道類的名稱,可以直接獲取一個類的Class。
- 通過Class類的forName(parameter)方法(常用)。這種方式是最常用的,在各類框架的配置檔案中可以看到,如:Spring、SpringMVC、Mybatis等等。其中,引數parameter為全限定類名(即:包名+類名),如:com.cya.test.Test。
7、通過反射獲取類中的方法
方法名稱 | 返回值 | 引數 | 說明 |
---|---|---|---|
getMethods() | Method [] | 無 | 獲取包括自身和繼承過來的所有的public方法 |
getDeclaredMethods() | Method [] | 無 | 獲取自身類中所有的方法(不包括繼承的,和訪問許可權無關) |
getMethod(String methodName,Class<?>... parameterTypes) | Method | methodName:表示被獲取方法的名字parameterTypes:表示被獲取方法的引數的Class型別,如String.class | 表示獲取指定的一個公共的方法(包括繼承的) |
getDeclaredMethod(String methodName,Class<?>... parameterTypes) | Method | methodName:表示被獲取方法的名字parameterTypes:表示被獲取方法的引數的Class型別,如 String.class | 表示獲取指定的一個本類中的方法(不包括繼承的) |
8、通過反射建立物件
java中,除了使用new關鍵字建立物件外,也可以用newInstance()方法建立物件,例如:
Class class1 = Class.forName("java.util.ArrayList");
List list=(List)class1.newInstance();
9、Method類的invoke()方法
public Object invoke(Object obj,Object args[])
作用:動態呼叫Method類代表的方法
obj:從中呼叫底層方法的物件,必須是例項化的物件
args:用於方法呼叫的引數,是個Object陣列,因為引數有可能有多個
obj可以為空,但必填null,表示同類中的公用方法
args引數可以為空,就是對應方法沒有引數
有關Java反射的詳細內容我將會專門出一期來講解,這裡只對本期用到的幾個重要的知識點做概述。
看完了上面的內容,你是不是對面試官的問題有解答思路了呢?下面給出小編自己的想法,如果你有更好的方法,記得跟大家分享哦。
10、思路分享
1、建立Integer型別的List集合,用於存放資料。
2、使用物件名.getClass()方法獲取Class物件。
3、呼叫getMethod()方法獲取指定的Method。
4、呼叫invoke()方法將不同資料型別的資料新增到list集合中。
11、程式碼實現
package com.cya.test;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class Test{
public static void main(String []args) throws Exception{
List<Integer> list=new ArrayList<>();
Object o;
//向list中新增Integer型別的資料
Integer integer=1;
o=integer;
Test.addObjectToList(list, o);
//向list中新增String型別的資料
String string="Hello World";
o=string;
Test.addObjectToList(list, o);
//向list中新增Character型別的資料
Character character='c';
o=character;
Test.addObjectToList(list, o);
//向list中新增Boolean型別的資料
Boolean boolean1=true;
o=boolean1;
Test.addObjectToList(list, o);
System.out.println(list);
}
public static List<Integer> addObjectToList(List<Integer> list, Object o) throws Exception{
Class class1=list.getClass();
Method method=class1.getMethod("add", Object.class);
method.invoke(list, o);
return list;
}
}
12、公眾號推薦(資源加油站)
瞭解更多資源請關注個人公眾號:C you again,你將收穫以下資源
1、PPT模板免費下載,簡歷模板免費下載
2、基於web的機票預訂系統,基於web的圖書管理系統
3、貪吃蛇小遊戲原始碼
4、各類IT技術分享
13、文章推薦
推薦一:計算機網路中這些高頻考題,你還在死記硬背嗎?(一),講述內容:IP地址及其分類,子網掩碼的概念,網路號、主機號、直接廣播地址計算方法等。
推薦二:計算機網路中這些高頻考題,你還在死記硬背嗎?(二),講述內容:區域網介面配置、路由器的靜態路由配置、OSPF動態路由協議配置和DHCP伺服器配置。
推薦三:用x種方式求第n項斐波那契數,99%的人只會第一種,講述內容:七種方式求解第N項斐波那契數。
以上就是本期的所有內容了,是否對你有幫助呢?瞭解更多演算法請關注公眾號“C you again”。
演示地址:點選檢視演示
我的部落格即將同步至騰訊雲+社群,邀請大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=23fno6ydwkbo4