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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java 反射练习

發(fā)布時(shí)間:2024/10/12 java 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java 反射练习 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

已同步更新至個(gè)人blog:http://dxjia.cn/2015/08/java-reflect/ ? ?

  引用baidubaike上對(duì)JAVA反射的說(shuō)明,如下:JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法(成員變量和函數(shù));對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語(yǔ)言的反射機(jī)制。

? ? 而能夠使JAVA有這樣的能力,歸根結(jié)底是由于JVM,而小一點(diǎn)說(shuō),是因?yàn)橛蠧lass對(duì)象的存在,我在上一篇文章中有講解JAVA的Class對(duì)象,它是在類加載完后,每個(gè)類都會(huì)產(chǎn)生的一個(gè)實(shí)例,而其內(nèi)部詳細(xì)描述了這個(gè)類的情況,所以我們可以通過(guò)這個(gè)Class對(duì)象來(lái)得到任何有關(guān)這個(gè)類的細(xì)節(jié),不僅僅能了解這個(gè)類,java還提供了方法來(lái)動(dòng)態(tài)執(zhí)行這個(gè)類里的方法或修改成員變量的值。

反射機(jī)制的優(yōu)點(diǎn)與缺點(diǎn):(參考:【Java反射機(jī)制】)

為什么要用反射機(jī)制?直接創(chuàng)建對(duì)象不就可以了嗎,這就涉及到了動(dòng)態(tài)與靜態(tài)的概念,
  靜態(tài)編譯:在編譯時(shí)確定類型,綁定對(duì)象,即通過(guò)。
  動(dòng)態(tài)編譯:運(yùn)行時(shí)確定類型,綁定對(duì)象。動(dòng)態(tài)編譯最大限度發(fā)揮了java的靈活性,體現(xiàn)了多態(tài)的應(yīng)用,有以降低類之間的藕合性。
  一句話,反射機(jī)制的優(yōu)點(diǎn)就是可以實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建對(duì)象和編譯,體現(xiàn)出很大的靈活性,特別是在J2EE的開(kāi)發(fā)中它的靈活性就表現(xiàn)的十分明顯。比如,一個(gè)大型的軟件,不可能一次就把把它設(shè)計(jì)的很完美,當(dāng)這個(gè)程序編
譯后,發(fā)布了,當(dāng)發(fā)現(xiàn)需要更新某些功能時(shí),我們不可能要用戶把以前的卸載,再重新安裝新的版本,假如這樣的話,這個(gè)軟件肯定是沒(méi)有多少人用的。采用靜態(tài)的話,需要把整個(gè)程序重新編譯一次才可以實(shí)現(xiàn)功能
的更新,而采用反射機(jī)制的話,它就可以不用卸載,只需要在運(yùn)行時(shí)才動(dòng)態(tài)的創(chuàng)建和編譯,就可以實(shí)現(xiàn)該功 能。
  它的缺點(diǎn)是對(duì)性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什么并且它滿足我們的要求。這類操作總是慢于只直接執(zhí)行相同的操作。

?

下面是我的練習(xí)程序:

在目錄下新建com\dxjia\sample路徑,然后在sample下新建一個(gè)UserBean.java的文件,這將是我們用來(lái)進(jìn)行反射的類。代碼如下:

1 package com.dxjia.sample; 2 3 public class UserBean { 4 private String mName; 5 private int mAge; 6 private String mVersion = "1.0"; 7 8 public UserBean() { 9 System.out.println(" UserBean Constructor1 called!"); 10 } 11 12 public UserBean(String name, int age) { 13 System.out.println(" UserBean Constructor2 called!"); 14 init(name, age); 15 } 16 17 public void setName(String name) { 18 mName = name; 19 System.out.println(" UserBean setName() done"); 20 } 21 22 public String getName() { 23 return mName; 24 } 25 26 public void setAge(int age) { 27 mAge = age; 28 System.out.println(" UserBean setAge() done"); 29 } 30 31 public int getAge() { 32 return mAge; 33 } 34 35 private void init(String name, int age) { 36 mName = name; 37 mAge = age; 38 } 39 40 public void printVersion() { 41 System.out.println(" UserBean VERSION: " + mVersion); 42 } 43 44 public void printName() { 45 System.out.println(" UserBean mName [" + mName + "]"); 46 } 47 48 public void printAge() { 49 System.out.println(" UserBean mAge [" + mAge + "]"); 50 } 51 52 private void printUserInfo() { 53 System.out.println(" UserBean mName [" + mName + "] " + "mAge [" + mAge + "]"); 54 } 55 }

然后在根目錄下新建Test.java文件,這里實(shí)現(xiàn)我們的測(cè)試程序,代碼如下【注意注釋】:

1 import java.lang.*; 2 import java.lang.reflect.*; 3 4 public class Test { 5 6 public static void main(String[] args) { 7 8 try { 9 Class c = Class.forName("com.dxjia.sample.UserBean"); 10 if (null == c) { 11 System.out.println("can`t load class!"); 12 return; 13 } 14 15 System.out.println("\n--------------獲取類的所有信息----------------------\n"); 16 17 // 獲取類的修飾符,public private... 18 int mod = c.getModifiers(); 19 String modifier = Modifier.toString(mod); 20 System.out.println("modifier : " + modifier); 21 22 // 獲取父類 23 Class superClass = c.getSuperclass(); 24 String superClassName = superClass.getName(); 25 System.out.println("superClassName : " + superClassName); 26 27 // 獲取implements的接口 28 Class[] interfaces = c.getInterfaces(); 29 if (interfaces.length != 0) { 30 for (Class cl : interfaces) { 31 System.out.println("interfacesName : " + cl.getName()); 32 } 33 } else { 34 System.out.println("interfacesName : "); 35 } 36 37 // 獲取所有的成員變量 38 Field[] fields = c.getDeclaredFields(); 39 if (fields.length != 0) { 40 System.out.println("fields : "); 41 for (Field field : fields) { 42 modifier = Modifier.toString(field.getModifiers()); 43 Class type = field.getType(); 44 String name = field.getName(); 45 if (type.isArray()) { 46 String arrType = type.getComponentType().getName() + "[]"; 47 System.out.println(" " + modifier + " " + arrType + " " + name + ";"); 48 } else { 49 System.out.println(" " + modifier + " " + type + " " + name + ";"); 50 } 51 } 52 } else { 53 System.out.println("fields : "); 54 } 55 56 // 獲取所有的構(gòu)造函數(shù) 57 Constructor[] constructors = c.getDeclaredConstructors(); 58 if(constructors.length != 0) { 59 System.out.println("constructors : "); 60 for (Constructor constructor : constructors) { 61 // 構(gòu)造方法名 62 String name = constructor.getName(); 63 // 獲取訪問(wèn)修飾符,public private protected 64 modifier = Modifier.toString(constructor.getModifiers()); 65 System.out.print(" " + modifier +" " + name + "("); 66 // 獲取構(gòu)造方法中的所有參數(shù), paramTypes.length為0,說(shuō)明是無(wú)參構(gòu)造函數(shù) 67 Class[] paramTypes = constructor.getParameterTypes(); 68 for (int i = 0; i < paramTypes.length; i++) { 69 if (i > 0) { 70 System.out.print(", "); 71 } 72 if (paramTypes[i].isArray()) { 73 System.out.print(paramTypes[i].getComponentType().getName()+"[]"); 74 } else { 75 System.out.print(paramTypes[i].getName()); 76 } 77 } 78 System.out.print(")\n"); 79 } 80 } else { 81 System.out.println("constructors : "); 82 } 83 84 // 獲取所有的成員函數(shù) 85 Method[] methods = c.getDeclaredMethods(); 86 if(methods.length != 0) { 87 System.out.println("methods : "); 88 for (Method method: methods) { 89 // 獲取方法的描述符,private public protected... 90 modifier = Modifier.toString(method.getModifiers()); 91 // 獲取方法的返回類型 92 Class returnType = method.getReturnType(); 93 if (returnType.isArray()) { 94 String arrType = returnType.getComponentType().getName()+"[]"; 95 System.out.print(" " + modifier + " " + arrType + " " + method.getName() + "("); 96 } else { 97 System.out.print(" " + modifier + " " + returnType.getName() + " " + method.getName() + "("); 98 } 99 // 獲取所有的參數(shù)信息 100 Class[] paramTypes = method.getParameterTypes(); 101 for (int i = 0; i < paramTypes.length; i++) { 102 if (i > 0) { 103 System.out.print(","); 104 } 105 if (paramTypes[i].isArray()) { 106 System.out.println(paramTypes[i].getComponentType().getName()+"[]"); 107 } else { 108 System.out.print(paramTypes[i].getName()); 109 } 110 } 111 System.out.println(");"); 112 } 113 } else { 114 System.out.println("methods : "); 115 } 116 117 System.out.println("\n----------------測(cè)試使用----------------------\n"); 118 119 /** 120 * 測(cè)試反射,調(diào)用函數(shù),變量賦值等 121 * 反射的使用一般都會(huì)先像上面這樣打印出來(lái),進(jìn)行一個(gè)分析之后, 122 * 再編寫類似下面的代碼來(lái)反射調(diào)用類的函數(shù),也就是自己先通過(guò)上面的方式來(lái)了解這個(gè)類, 123 * 然后再hard code反射使用這個(gè)類中對(duì)自己有用的函數(shù)來(lái)達(dá)到目的。當(dāng)然,我們比較了解那個(gè)類了,只是環(huán)境中沒(méi)有公開(kāi),所以我們需要反射 124 */ 125 // 首先可以實(shí)例化對(duì)象,因?yàn)槿f(wàn)物都繼承自O(shè)bject 126 // 所以這里用Object來(lái)聲明定義對(duì)象,不影響使用 127 // 直接使用Class.newInstance()函數(shù),是調(diào)用的類的無(wú)參構(gòu)造函數(shù) 128 System.out.println("調(diào)用無(wú)參構(gòu)造函數(shù)"); 129 Object bean1 = c.newInstance(); 130 131 // 如果要調(diào)用有參構(gòu)造函數(shù),那就要使用下面的方式 132 Class[] paramTypes = {String.class, int.class}; 133 Constructor con = c.getConstructor(String.class, int.class); 134 // 使用 135 System.out.println("調(diào)用有參構(gòu)造函數(shù)"); 136 Object bean2 = con.newInstance("小明", 16); 137 138 // 調(diào)用bean2 public 函數(shù) printVersion() 139 System.out.println("執(zhí)行public printVersion()"); 140 Method method1 = c.getDeclaredMethod("printVersion"); 141 method1.invoke(bean2); 142 143 // 調(diào)用bean2 private函數(shù) printUserInfo() 144 System.out.println("執(zhí)行public printUserInfo()"); 145 Method method2 = c.getDeclaredMethod("printUserInfo"); 146 // 因?yàn)閜rintUserInfo是private方法,所以需要加上這句來(lái)避免安全檢查,這樣才可以調(diào)用私有方法 147 method2.setAccessible(true); 148 // 執(zhí)行 149 method2.invoke(bean2); 150 151 // 調(diào)用有參數(shù)的函數(shù) setName() setAge() 152 System.out.println("調(diào)用有參數(shù)函數(shù)設(shè)置新name和age"); 153 Method method3 = c.getDeclaredMethod("setName", String.class); 154 method3.invoke(bean2, "張三"); 155 Method method4 = c.getDeclaredMethod("setAge", int.class); 156 method4.invoke(bean2, 25); 157 158 // 調(diào)用 printUserInfo 將新值打印出來(lái) 159 System.out.println("打印新值"); 160 method2.invoke(bean2); 161 162 // 直接操作成員變量,給私有成員變量賦值,記得加setAccessible(true); 163 Field field = c.getDeclaredField("mVersion"); 164 field.setAccessible(true); 165 String oldVersion = (String) field.get(bean2); 166 System.out.println("直接獲取私有變量mVersion的值,并打印:" + oldVersion); 167 System.out.println("直接將私有成員變量mVersion賦值2.0"); 168 field.set(bean2, "2.0"); 169 // 調(diào)用printVersion()打印新值 170 System.out.println("打印新值"); 171 method1.invoke(bean2); 172 } catch (ClassNotFoundException e) { 173 System.out.println("exception: " + e.toString()); 174 } catch (InstantiationException e) { 175 System.out.println("exception: " + e.toString()); 176 } catch (IllegalAccessException e) { 177 System.out.println("exception: " + e.toString()); 178 } catch (NoSuchMethodException e) { 179 System.out.println("exception: " + e.toString()); 180 } catch (InvocationTargetException e) { 181 System.out.println("exception: " + e.toString()); 182 } catch (NoSuchFieldException e) { 183 System.out.println("exception: " + e.toString()); 184 } 185 } 186 187 }

打開(kāi)cmd,切換到該目錄下,執(zhí)行

1 javac com\dxjia\sample\UserBean.java 2 javac -encoding UTF-8 -Xlint:unchecked Test.java

編譯通過(guò)后,執(zhí)行:

1 java Test

打印如下:

--------------獲取類的所有信息----------------------modifier : public superClassName : java.lang.Object interfacesName : fields :private class java.lang.String mName;private int mAge;private class java.lang.String mVersion; constructors :public com.dxjia.sample.UserBean()public com.dxjia.sample.UserBean(java.lang.String, int) methods :public int getAge();public void printName();public void printAge();public java.lang.String getName();private void init(java.lang.String,int);public void setName(java.lang.String);public void setAge(int);public void printVersion();private void printUserInfo();----------------測(cè)試使用----------------------調(diào)用無(wú)參構(gòu)造函數(shù)UserBean Constructor1 called! 調(diào)用有參構(gòu)造函數(shù)UserBean Constructor2 called! 執(zhí)行public printVersion()UserBean VERSION: 1.0 執(zhí)行public printUserInfo()UserBean mName [小明] mAge [16] 調(diào)用有參數(shù)函數(shù)設(shè)置新name和ageUserBean setName() doneUserBean setAge() done 打印新值UserBean mName [張三] mAge [25] 直接獲取私有變量mVersion的值,并打印:1.0 直接將私有成員變量mVersion賦值2.0 打印新值UserBean VERSION: 2.0

?

轉(zhuǎn)載于:https://www.cnblogs.com/flyme/p/4577113.html

總結(jié)

以上是生活随笔為你收集整理的Java 反射练习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。