国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Java反射技術(shù)詳解及實(shí)例解析

瀏覽:6日期:2022-08-29 11:20:07

前言

相信很多人都知道反射可以說(shuō)是Java中最強(qiáng)大的技術(shù)了,它可以做的事情太多太多,很多優(yōu)秀的開(kāi)源框架都是通過(guò)反射完成的,比如最初的很多注解框架,后來(lái)因?yàn)閖ava反射影響性能,所以被運(yùn)行時(shí)注解APT替代了,java反射有個(gè)開(kāi)源框架jOOR相信很多人都用過(guò),不過(guò)我們還是要學(xué)習(xí)反射的基礎(chǔ)語(yǔ)法,這樣才能自己寫(xiě)出優(yōu)秀的框架,當(dāng)然這里所講的反射技術(shù),是學(xué)習(xí)Android插件化技術(shù)、Hook技術(shù)等必不可少的!

一、基本反射技術(shù)

1.1 根據(jù)一個(gè)字符串得到一個(gè)類(lèi)

getClass方法

String name = 'Huanglinqing'; Class c1 = name.getClass(); System.out.println(c1.getName());

打印結(jié)果如下:

Java反射技術(shù)詳解及實(shí)例解析

Class.forName

比如我們獲取java.lang.String的類(lèi)名

String name = 'java.lang.String'; Class c1 = null; try { c1 = Class.forName(name); System.out.println(c1.getName()); } catch (ClassNotFoundException e) { }

這里也通過(guò)捕獲異常,因?yàn)槲覀儌鞯倪@個(gè)字符串可能不合法,字符串合法命名是類(lèi)的命名空間和類(lèi)的名稱(chēng)組成

打印結(jié)果如下:

Java反射技術(shù)詳解及實(shí)例解析

我們還可以通過(guò)c1.getSuperclass()獲取到他的父類(lèi)

Type屬性

基本類(lèi)型都有type屬性,可以得到這個(gè)基本類(lèi)型的類(lèi)型,比如:

Class c1 = Boolean.TYPE;Class c2 = Byte.TYPE;Class c3 = Float.TYPE;Class c4 = Double.TYPE;

停停停!這些東西有啥子用,如此雞肋! 別急,一切都是為后續(xù)做準(zhǔn)備。

二、獲取類(lèi)的成員

當(dāng)類(lèi)中方法定義為私有的時(shí)候我們能調(diào)用?不能!當(dāng)變量是私有的時(shí)候我們能獲取嗎?不能!但是反射可以,比如源碼中有你需要用到的方法,但是那個(gè)方法是私有的,這個(gè)時(shí)候你就可以通過(guò)反射去執(zhí)行這個(gè)私有方法,并且獲取私有變量。

獲取類(lèi)的構(gòu)造函數(shù)

為了便于測(cè)試,我們定義一個(gè)Test類(lèi),Test類(lèi)如下:(省略get和set方法)

Test類(lèi)中我們定義是三個(gè)私有變量,生成兩個(gè)公有的含參構(gòu)造方法和一個(gè)私有的含參構(gòu)造方法以及一個(gè)公有的無(wú)參構(gòu)造方法。

public class Test { private int age; private String name; private int testint; public Test(int age) { this.age = age; } public Test(int age, String name) { this.age = age; this.name = name; } private Test(String name) { this.name = name; } public Test() { }

下面我們通過(guò)反射獲取這些構(gòu)造方法

獲取類(lèi)的所有構(gòu)造方法

Test test = new Test(); Class c4 = test.getClass(); Constructor[] constructors ; constructors = c4.getDeclaredConstructors();

通過(guò)getDeclaredConstructors可以返回類(lèi)的所有構(gòu)造方法,返回的是一個(gè)數(shù)組因?yàn)闃?gòu)造方法可能不止一個(gè),通過(guò)getModifiers可以得到構(gòu)造方法的類(lèi)型,getParameterTypes可以得到構(gòu)造方法的所有參數(shù),返回的是一個(gè)Class數(shù)組,所以我們?nèi)绻氆@取所有構(gòu)造方法以及每個(gè)構(gòu)造方法的參數(shù)類(lèi)型,可以有如下代碼:

for (int i = 0; i < constructors.length; i++) { System.out.print(Modifier.toString(constructors[i].getModifiers()) + '參數(shù):'); Class[] parametertypes = constructors[i].getParameterTypes(); for (int j = 0; j < parametertypes.length; j++) { System.out.print(parametertypes[j].getName() + ' '); } System.out.println(''); }

運(yùn)行結(jié)果如下所示:

Java反射技術(shù)詳解及實(shí)例解析

這樣我們就得到了類(lèi)中所有構(gòu)造方法和構(gòu)造方法中的參數(shù),那么我們?nèi)绾潍@取特定的構(gòu)造方法呢?

獲取類(lèi)中特定的構(gòu)造方法

我們可以通過(guò)getConstructors方法獲取類(lèi)中 所有的public類(lèi)型的構(gòu)造方法,代碼和上面一樣就不演示了。

我們可以通過(guò)getDeclaredConstructor()方法傳參獲取特定參數(shù)類(lèi)型的構(gòu)造方法,這里注意是getDeclaredConstructor()不是 getDeclaredConstructors() ,所以返回的是一個(gè)Class對(duì)象而不是一個(gè)Class數(shù)組。

獲取無(wú)參構(gòu)造方法直接不傳參數(shù),如下所示:

try { constructors = c4.getDeclaredConstructor(); System.out.print(Modifier.toString(constructors.getModifiers()) + ); } catch (NoSuchMethodException e) { e.printStackTrace(); }

這里要進(jìn)行異常捕獲,因?yàn)榭赡懿淮嬖趯?duì)應(yīng)的構(gòu)造方法,打印結(jié)果如下:

Java反射技術(shù)詳解及實(shí)例解析

如果我們想獲取有兩個(gè)參數(shù)分別為int和String類(lèi)型的構(gòu)造方法,代碼如下:

Class[] p = {int.class,String.class}; try { constructors = c4.getDeclaredConstructor(p); System.out.print(Modifier.toString(constructors.getModifiers()) + '參數(shù):'); Class[] parametertypes = constructors.getParameterTypes(); for (int j = 0; j < parametertypes.length; j++) { System.out.print(parametertypes[j].getName() + ' '); } } catch (NoSuchMethodException e) { e.printStackTrace(); }

這里我們同樣打印出構(gòu)造方法的參數(shù):

Java反射技術(shù)詳解及實(shí)例解析

調(diào)用構(gòu)造方法

從這里開(kāi)始慢慢到了關(guān)鍵的一步,得到類(lèi)的實(shí)例,我們主要借助于newInstance方法,為了方便演示我們將測(cè)試類(lèi)的兩個(gè)構(gòu)造方法打印出來(lái).

public Test(int age, String name) { this.age = age; this.name = name; System.out.println('hello' + name + 'i am' + age); } private Test(String name) { this.name = name; System.out.println('My Name is' + name); }

我們先來(lái)調(diào)用public的方法,如下所示:

Class[] p = {int.class,String.class}; constructors = c4.getDeclaredConstructor(p); constructors.newInstance(24,'HuangLinqing');

運(yùn)行打印結(jié)果如下:

Java反射技術(shù)詳解及實(shí)例解析

那么調(diào)用私有構(gòu)造方法呢,和上面一樣,只是我們要設(shè)置constructors.setAccessible(true);代碼如下:

Class[] p = {String.class}; constructors = c4.getDeclaredConstructor(p); constructors.setAccessible(true); constructors.newInstance('HuangLinqing');

打印結(jié)果如下:

Java反射技術(shù)詳解及實(shí)例解析

調(diào)用類(lèi)的私有方法

如何調(diào)用類(lèi)中的私有方法呢,我們先在測(cè)試類(lèi)中編寫(xiě)一個(gè)測(cè)試的私有方法 如下:

private void welcome(String tips){ System.out.println(tips); }

我們知道如果我們要正常的調(diào)用類(lèi)的方法都是通過(guò)類(lèi).方法調(diào)用,所以我們調(diào)用私有方法也需要得到類(lèi)的實(shí)例,而我們上面newInstace已經(jīng)得到了類(lèi)的實(shí)例,這樣就好辦了。

Class[] p4 = {String.class}; Method method = c4.getDeclaredMethod('welcome',p4); method.setAccessible(true);

我們首先通過(guò) getDeclaredMethod方法獲取到這個(gè)私有方法,第一個(gè)參數(shù)是方法名,第二個(gè)參數(shù)是參數(shù)類(lèi)型

然后通過(guò)invoke方法執(zhí)行,invoke需要兩個(gè)參數(shù)一個(gè)是類(lèi)的實(shí)例,一個(gè)是方法參數(shù)。

Class[] p4 = {String.class}; Method method = c4.getDeclaredMethod('welcome',p4); method.setAccessible(true); Object arg1s[] = {'歡迎關(guān)注代碼男人技術(shù)公眾號(hào)'}; method.invoke(test,arg1s);

test類(lèi)的實(shí)例當(dāng)不能new 獲取的時(shí)候我們也可以通過(guò)反射獲取,就是上面的newInstance方法。打印結(jié)果如下:

Java反射技術(shù)詳解及實(shí)例解析

獲取類(lèi)的私有字段并修改值

看到這里你可能會(huì)說(shuō),有了set方法,什么私有不私有,test.set不就可以了,但是這里要注意我們是沒(méi)有辦法得到這個(gè)類(lèi)的實(shí)例的,要不然都可以得到實(shí)例就沒(méi)有反射一說(shuō)了。我們?cè)谕ㄟ^(guò)反射得到類(lèi)的實(shí)例之后先獲取字段:

Field field = c4.getDeclaredField('name');field.setAccessible(true);field.set(o,'代碼男人');

o是我們上面通過(guò)反射構(gòu)造方法獲取的實(shí)例, 打印field.get(o).toString()的值如下:

Java反射技術(shù)詳解及實(shí)例解析

不過(guò)要注意的是我們修改了name的值只對(duì)當(dāng)前的實(shí)例對(duì)象有效。

Java的基本反射語(yǔ)法就是這樣了,歡迎加入技術(shù)群一起探討!

最后反射封裝類(lèi)如下:

package jnidemo.hlq.com.hookdemo; import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method; /** * @author Huanglinqing * @date 2019/4/28 */ public class Reflex { /** * 獲取無(wú)參構(gòu)造函數(shù) * @param className * @return */ public static Object createObject(String className) { Class[] pareTyples = new Class[]{}; Object[] pareVaules = new Object[]{}; try { Class r = Class.forName(className); return createObject(r, pareTyples, pareVaules); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } /** * 獲取無(wú)參構(gòu)造方法 * @param clazz * @return */ public static Object createObject(Class clazz) { Class[] pareTyple = new Class[]{}; Object[] pareVaules = new Object[]{}; return createObject(clazz, pareTyple, pareVaules); } /** * 獲取一個(gè)參數(shù)的構(gòu)造函數(shù) 已知className * * @param className * @param pareTyple * @param pareVaule * @return */ public static Object createObject(String className, Class pareTyple, Object pareVaule) { Class[] pareTyples = new Class[]{pareTyple}; Object[] pareVaules = new Object[]{pareVaule}; try { Class r = Class.forName(className); return createObject(r, pareTyples, pareVaules); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } /** * 獲取單個(gè)參數(shù)的構(gòu)造方法 已知類(lèi) * * @param clazz * @param pareTyple * @param pareVaule * @return */ public static Object createObject(Class clazz, Class pareTyple, Object pareVaule) { Class[] pareTyples = new Class[]{pareTyple}; Object[] pareVaules = new Object[]{pareVaule}; return createObject(clazz, pareTyples, pareVaules); } /** * 獲取多個(gè)參數(shù)的構(gòu)造方法 已知className * @param className * @param pareTyples * @param pareVaules * @return */ public static Object createObject(String className, Class[] pareTyples, Object[] pareVaules) { try { Class r = Class.forName(className); return createObject(r, pareTyples, pareVaules); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } /** * 獲取構(gòu)造方法 * * @param clazz * @param pareTyples * @param pareVaules * @return */ public static Object createObject(Class clazz, Class[] pareTyples, Object[] pareVaules) { try { Constructor ctor = clazz.getDeclaredConstructor(pareTyples); ctor.setAccessible(true); return ctor.newInstance(pareVaules); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 獲取多個(gè)參數(shù)的方法 * @param obj * @param methodName * @param pareTyples * @param pareVaules * @return */ public static Object invokeInstanceMethod(Object obj, String methodName, Class[] pareTyples, Object[] pareVaules) { if (obj == null) { return null; } try { //調(diào)用一個(gè)private方法 //在指定類(lèi)中獲取指定的方法 Method method = obj.getClass().getDeclaredMethod(methodName, pareTyples); method.setAccessible(true); return method.invoke(obj, pareVaules); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 獲取一個(gè)參數(shù)的方法 * @param obj * @param methodName * @param pareTyple * @param pareVaule * @return */ public static Object invokeInstanceMethod(Object obj, String methodName, Class pareTyple, Object pareVaule) { Class[] pareTyples = {pareTyple}; Object[] pareVaules = {pareVaule}; return invokeInstanceMethod(obj, methodName, pareTyples, pareVaules); } /** * 獲取無(wú)參方法 * @param obj * @param methodName * @return */ public static Object invokeInstanceMethod(Object obj, String methodName) { Class[] pareTyples = new Class[]{}; Object[] pareVaules = new Object[]{}; return invokeInstanceMethod(obj, methodName, pareTyples, pareVaules); } /** * 無(wú)參靜態(tài)方法 * @param className * @param method_name * @return */ public static Object invokeStaticMethod(String className, String method_name) { Class[] pareTyples = new Class[]{}; Object[] pareVaules = new Object[]{}; return invokeStaticMethod(className, method_name, pareTyples, pareVaules); } /** * 獲取一個(gè)參數(shù)的靜態(tài)方法 * @param className * @param method_name * @param pareTyple * @param pareVaule * @return */ public static Object invokeStaticMethod(String className, String method_name, Class pareTyple, Object pareVaule) { Class[] pareTyples = new Class[]{pareTyple}; Object[] pareVaules = new Object[]{pareVaule}; return invokeStaticMethod(className, method_name, pareTyples, pareVaules); } /** * 獲取多個(gè)參數(shù)的靜態(tài)方法 * @param className * @param method_name * @param pareTyples * @param pareVaules * @return */ public static Object invokeStaticMethod(String className, String method_name, Class[] pareTyples, Object[] pareVaules) { try { Class obj_class = Class.forName(className); return invokeStaticMethod(obj_class, method_name, pareTyples, pareVaules); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 無(wú)參靜態(tài)方法 * @param method_name * @return */ public static Object invokeStaticMethod(Class clazz, String method_name) { Class[] pareTyples = new Class[]{}; Object[] pareVaules = new Object[]{}; return invokeStaticMethod(clazz, method_name, pareTyples, pareVaules); } /** * 一個(gè)參數(shù)靜態(tài)方法 * @param clazz * @param method_name * @param classType * @param pareVaule * @return */ public static Object invokeStaticMethod(Class clazz, String method_name, Class classType, Object pareVaule) { Class[] classTypes = new Class[]{classType}; Object[] pareVaules = new Object[]{pareVaule}; return invokeStaticMethod(clazz, method_name, classTypes, pareVaules); } /** * 多個(gè)參數(shù)的靜態(tài)方法 * @param clazz * @param method_name * @param pareTyples * @param pareVaules * @return */ public static Object invokeStaticMethod(Class clazz, String method_name, Class[] pareTyples, Object[] pareVaules) { try { Method method = clazz.getDeclaredMethod(method_name, pareTyples); method.setAccessible(true); return method.invoke(null, pareVaules); } catch (Exception e) { e.printStackTrace(); } return null; } public static Object getFieldObject(String className, Object obj, String filedName) { try { Class obj_class = Class.forName(className); return getFieldObject(obj_class, obj, filedName); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } public static Object getFieldObject(Class clazz, Object obj, String filedName) { try { Field field = clazz.getDeclaredField(filedName); field.setAccessible(true); return field.get(obj); } catch (Exception e) { e.printStackTrace(); } return null; } public static void setFieldObject(Class clazz, Object obj, String filedName, Object filedVaule) { try { Field field = clazz.getDeclaredField(filedName); field.setAccessible(true); field.set(obj, filedVaule); } catch (Exception e) { e.printStackTrace(); } } public static void setFieldObject(String className, Object obj, String filedName, Object filedVaule) { try { Class obj_class = Class.forName(className); setFieldObject(obj_class, obj, filedName, filedVaule); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Object getStaticFieldObject(String className, String filedName) { return getFieldObject(className, null, filedName); } public static Object getStaticFieldObject(Class clazz, String filedName) { return getFieldObject(clazz, null, filedName); } public static void setStaticFieldObject(String classname, String filedName, Object filedVaule) { setFieldObject(classname, null, filedName, filedVaule); } public static void setStaticFieldObject(Class clazz, String filedName, Object filedVaule) { setFieldObject(clazz, null, filedName, filedVaule); }}

到此這篇關(guān)于Java反射技術(shù)詳解及實(shí)例解析的文章就介紹到這了,更多相關(guān)Java反射技術(shù)示例詳解內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 色射网 | 91影视永久福利免费观看 | 国产成人cao在线 | 亚洲视频综合网 | 久草天堂 | 日韩欧美成人乱码一在线 | 加勒比在线免费视频 | 久久精品国产福利 | 在线男人的天堂 | 久久久久久在线 | 黄视频免费在线 | 成人久久久观看免费毛片 | 国产精品久久免费观看 | 日本一区二区三区国产 | 欧美一级毛片免费观看视频 | 99精品久久99久久久久 | 国产永久在线视频 | 日本视频在线免费观看 | 亚洲欧美视频 | 可以免费观看欧美一级毛片 | 久久精品国产免费一区 | 免费观看毛片的网站 | 99国产在线 | 日韩精品免费一级视频 | 精品亚洲综合久久中文字幕 | 国产欧美日韩视频在线观看一区二区 | 国产91精品高清一区二区三区 | 被老外玩爽的中国美女视频 | 91久久精品| 久久在线观看免费视频 | 精品国产欧美一区二区三区成人 | 精品手机在线 | 成人免费视频日本 | 免费视频一区二区 | 黄页美女 | 精品国产乱码久久久久久一区二区 | 国产精品久久久久久久 | 2022国内精品免费福利视频 | 一区二区三区四区视频在线观看 | 久久免费视频在线观看30 | 国产在线精品一区二区 |