您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Java反射能做什么”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“Java反射能做什么”吧!
一、 什么是反射?
用在Java身上指的是我們可以于運(yùn)行時(shí)加載、探知、使用編譯期間完全未知的classes。換句話說(shuō),Java程序可以加載一個(gè)運(yùn)行時(shí)才得知名稱的class,獲悉其完整構(gòu)造(但不包括methods定義),并生成其對(duì)象實(shí)體、或?qū)ζ鋐ields設(shè)值、或喚起其methods。
如果你是一個(gè)Android Developer,前輩們都會(huì)教導(dǎo)你盡量少用反射,效率太低,太慢?!吧洹甭铮涞奶炀筒缓昧?,所以反射雖然慢點(diǎn),但是偶爾射一下還是很”爽”的。
二、反射能做什么?
1、新建類的實(shí)例
我們知道所有的類都繼承子***父類Object,而Object中有hashCode()、equals()、clone()、toString()、getClass()等。其中g(shù)etClass()返回一個(gè)Class 對(duì)象。我們這里就需要使用的Class對(duì)象,注意C是大寫,我們可以通過(guò)一下方式來(lái)獲取Class對(duì)象
Class.forName(“類名字符串”) (注意:類名字符串必須是全稱,包名+類名)
類名.class
實(shí)例對(duì)象.getClass()
在Class類中有一個(gè)非常重要的方法
public T newInstance() throws InstantiationException, IllegalAccessException { return newInstanceImpl(); } private native T newInstanceImpl() throws IllegalAccessException, InstantiationException;
查看Api可以看到調(diào)用newInstace方法可以返回當(dāng)前class對(duì)應(yīng)的實(shí)例對(duì)象。接下來(lái)看一個(gè)小的Demo
public class Reflection { public static void main(String[] args) { // 普通創(chuàng)建類的實(shí)例 People p1 = new People(); System.out.println(p1.getName()); // 利用反射獲取類的實(shí)例 Class clazz = People.class; // 常用方式,注意括號(hào)中需要放類的全路徑名 // Class clazz = Class.forName("reflection.People"); // Class clazz = p1.getClass(); try { People p2 = (People) clazz.newInstance(); System.out.println(p2.getName()); } catch (Exception e) { e.printStackTrace(); } } } class People { private String name = "張三"; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
輸入結(jié)果:
張三 張三
2、獲取成員變量和方法
在講之前我們先來(lái)看這樣一個(gè)小按理,JSON數(shù)據(jù)轉(zhuǎn)JavaBaen對(duì)象,在不用解析庫(kù)的情況下,一般我們會(huì)這樣做
private void analysisDate(JSONObject response) throws JSONException { int announceid = response.getInt("announceid"); String title = response.getString("title"); String hits = response.getString("hits"); String addtime = response.getString("addtime"); NewsNotifyItem newsNotifyItem = new NewsNotifyItem(announceid, title, hits, addtime); } }
下面是我寫的一個(gè)JsonObject對(duì)象轉(zhuǎn)JavaBean的一個(gè)工具類,需要注意的是,JSON的key需要和字段名保持一致,先說(shuō)下思路
①首先通過(guò)反射獲取JavaBean中的所有字段值的名稱
②拼接出set方法
③由于字段名和Json的key值相同,利用自動(dòng)名獲取Json中的值并填充的實(shí)例對(duì)象中
public class Json2BeanUtils { public static <T> T jsonToBean(JSONObject response, Class<T> clazz) { try { // 創(chuàng)建類的實(shí)例 Object object = Class.forName(clazz.getName()).newInstance(); // 獲取類中的所有成員變量 Field[] fields = object.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { //設(shè)置權(quán)限 fields[i].setAccessible(true); // 獲取字段的名稱 String fieldName = fields[i].getName(); // 過(guò)濾掉UID if (fieldName.endsWith("serialVersionUID")) { continue; } // 獲取字段的類型 String fieldType = fields[i].getGenericType().toString(); // 拼接出JavaBean中的set方法 這里有一個(gè)坑 后面講解 String methodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); try { // 判斷變量類型 if (fieldType.endsWith("class java.lang.String")) { // 獲取到set方法 Method m = object.getClass().getMethod(methodName, String.class); String value = null; try { // 從JsonObj中取出相應(yīng)的值 value = response.getString(fieldName); } catch (Exception e) { e.printStackTrace(); value = ""; } if (TextUtils.isEmpty(value)) { value = ""; } else if (value.endsWith("null")) { value = ""; } // 賦值 m.invoke(object, value); } else if (fieldType.endsWith("int") || fieldType.endsWith("class java.lang.Integer")) { // int 類型 System.out.println(); Method m = object.getClass().getMethod(methodName, int.class); int value = -1; try { value = response.getInt(fieldName); } catch (Exception e) { e.printStackTrace(); value = -1; } m.invoke(object, value); } else if (fieldType.endsWith("boolean") || fieldType .endsWith("fieldType:class java.lang.Boolean")) { // boolean 類型 Method m = object.getClass().getMethod(methodName, boolean.class); boolean value = false; try { value = response.getBoolean(fieldName); } catch (Exception e) { e.printStackTrace(); value = false; } m.invoke(object, value); } else if (fieldType.endsWith("double") || fieldType .endsWith("fieldType:class java.lang.Double")) { // double 類型 Method m = object.getClass().getMethod(methodName, double.class); double value = -1D; try { value = response.getDouble(fieldName); } catch (Exception e) { e.printStackTrace(); value = -1D; } m.invoke(object, value); } else if (fieldType.endsWith("char")) { // char類型 JSONObject 沒(méi)有char Method m = object.getClass().getMethod(methodName, String.class); String value = ""; try { value = response.getString(fieldName); } catch (Exception e) { e.printStackTrace(); value = ""; } m.invoke(object, value); } else if (fieldType.endsWith("float") || fieldType .endsWith("fieldType:class java.lang.Float")) { // float類型 Method m = object.getClass().getMethod(methodName, double.class); double value = -1D; try { value = response.getDouble(fieldName); } catch (Exception e) { e.printStackTrace(); value = -1D; } m.invoke(object, value); } else if (fieldType.endsWith("short") || fieldType .endsWith("fieldType:class java.lang.Short")) { // short Method m = object.getClass().getMethod(methodName, short.class); int value = -1; try { value = response.getInt(fieldName); } catch (Exception e) { e.printStackTrace(); value = -1; } m.invoke(object, value); } else if (fieldType.endsWith("byte") || fieldType .endsWith("fieldType:class java.lang.Byte")) { Method m = object.getClass().getMethod(methodName, byte.class); int value = -1; try { value = response.getInt(fieldName); } catch (Exception e) { e.printStackTrace(); value = -1; } m.invoke(object, value); } else if (fieldType.endsWith("long") || fieldType .endsWith("fieldType:class java.lang.Long")) { Method m = object.getClass().getMethod(methodName, long.class); Long value = -1L; try { value = response.getLong(fieldName); } catch (Exception e) { e.printStackTrace(); value = -1L; } m.invoke(object, value); } } catch (Exception e) { // TODO: handle exception } } return (T) object; } catch (Exception e) { e.printStackTrace(); } return null; } }
這里需要注意一個(gè)坑,先來(lái)看一段代碼
class People { private String name; private int age; private String mSex; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getmSex() { return mSex; } // 這里就出了問(wèn)題 public void setmSex(String mSex) { this.mSex = mSex; } }
當(dāng)我們自動(dòng)生成get set方法時(shí),會(huì)將字段的首字母大寫,我們?cè)谏厦嫫唇觭et 方法時(shí),也是基于這樣的規(guī)則來(lái)拼裝的。但是 當(dāng)我們的字段名為 aAbbb 時(shí),則生成的get set 方法則不會(huì)大寫。解決方案也很簡(jiǎn)單,注意字段命名或者在拼接時(shí)對(duì)第二個(gè)自動(dòng)進(jìn)行大小寫判斷。這樣我們自己寫的Json解析工具就搞定, 以后每次解析只需一行代碼即可OK。
到此,相信大家對(duì)“Java反射能做什么”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。