Java反射 二三事
为什么需要反射
对私有方法反射的主要流程
1.首先获得方法A所在类的Class object,即通过Class.forName(ClassName)以及 object.newInstance()获得。
注意这里的ClassName包含类所在的包名。
2.利用刚才得到的Class object调用getDeclaredMethod(String name, Class<?>... parameterTypes)方法。前一个参数是nonpublic方法A的名字,后面的参数是包含方法A的各个参数的类型的Class Object。这样就可以得到方法A的object,原文描述为:Returns a Method object that reflects the specified declared method of the class or interface represented by this Class object。
Method A’= getDeclaredMethod(“A”,Class<?>... parameterTypesOf”A”) 也可以保留方法A原名,这里为了区分命名为A’。
3.设置方法A’的可见性A’.setAccessible(true);
4.调用A’方法,注意一定要invoke()====>A’.invoke(A所在类的Classobject, A的参数)。
对私有字段反射的主要流程
1.和私有方法的反射类似
2.利用刚才得到的Class object调用getDeclaredField(String fieldName)获取字段对象fieldObj。
3.设置字段可见性fieldObj.setAccessible(true);
4.设置字段fieldObj.set(object, value)
获取字段的值fieldObj.get(object)
一个基本和典型的私有方法反射示例
(1)写个类
package xxx.yyy.zzzpublic class Simple {private void displayMessage(String strMsg) {System.out.println("message is:" + strMsg);}}
(2)反射调用import java.lang.reflect.*;public class Test {public static void main(String[] args) throws ClassNotFoundException,SecurityException, NoSuchMethodException, InstantiationException,IllegalAccessException, IllegalArgumentException,InvocationTargetException {Class simpleClass = Class.forName("xxx.yyy.zzz.Simple");Object simpelObject = simpleClass.newInstance();Class[] args1 = new Class[1];args1[0] = String.class;Method simpleMethod = simpleClass.getDeclaredMethod("displayMessage",arg1);simpleMethod.setAccessible(true);String[] argments = new String[1];argments[0] = "Hello,world";simpleMethod.invoke(simpelObject, argments);}}
复杂参数类型的反射示例
package org.apache.nutch.parse.html;public class TestOnly {private String[] array= new String[4];private String[] getStringArray(){return array;}private void setStringArray(String[] values){array=values;}}
它的array数据和对应的set/get方法都是私有的
package org.apache.nutch.parse.html;import org.junit.Test;import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;import static org.junit.Assert.*;public class TestOnlyTest {@Testpublic void testGetStringArray() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,IllegalAccessException, InstantiationException, MalformedURLException, NoSuchFieldException {Class testObj = Class.forName("org.apache.nutch.parse.html.TestOnly");Object obj = testObj.newInstance();/*test set method.*/Method setArray = testObj.getDeclaredMethod("setStringArray", new Class[]{String[].class});setArray.setAccessible(true);String[] name = {"hello", "world"};setArray.invoke(obj, new Object[]{name});/*test get method.*/Method getArray = testObj.getDeclaredMethod("getStringArray");getArray.setAccessible(true);String[] result = (String[])getArray.invoke(obj);assertEquals("hello",result[0]);assertEquals("world",result[1]);/*test private field visit.*/Field array =testObj.getDeclaredField("array");array.setAccessible(true);array.set(obj, new String[]{"come","here","baby"});result = (String[])array.get(obj);assertEquals("come",result[0]);assertEquals("here",result[1]);assertEquals("baby",result[2]);}
}
当然不用单元测试,也可以用通过打印语句来验证结果集的正确性。
@Overridepublic ArrayList<Outlink> filterOutlinks(ArrayList<Outlink> list) {ArrayList<Outlink> filterList = new ArrayList<Outlink>();Outlink filterLink = null;for (Outlink outlink : list) {if (isCrawlOutLineUrl(outlink.getToUrl())) {try {filterLink = new Outlink(outlink.getToUrl(), "ydss");} catch (MalformedURLException e) {dMsg.warn("MalformedURLException:", e);continue;}if (!filterList.contains(filterLink)) {filterList.add(filterLink);}}}return filterList;}
其中isCrawlOutLineUrl是一个判断是否为合法出链的私有方法,具体逻辑忽略,此外用到了一个私有字段url。
// @Testpublic void testIsCrawlOutLineUrl() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,IllegalAccessException, InstantiationException, NoSuchFieldException{String outLinkUrl = "http://bbs.ydss.cn/thread-199593-1-1.html";Class ypObj = Class.forName("org.apache.nutch.parse.html.YdssParser");Object yp = ypObj.newInstance();Method isCrawlOutLineUrl = ypObj.getDeclaredMethod("isCrawlOutLineUrl", new Class[]{String.class});isCrawlOutLineUrl.setAccessible(true);Field url = ypObj.getDeclaredField("url");url.setAccessible(true);url.set(yp, "http://bbs.ydss.cn/forum.php?mod=viewthread&tid=505896&extra=page%3D1%26filter%3Dauthor%26orderby%3Ddateline");assertFalse((Boolean) isCrawlOutLineUrl.invoke(yp, outLinkUrl));outLinkUrl = "http://bbs.ydss.cn/thread-505896-1-1.html";assertFalse((Boolean) isCrawlOutLineUrl.invoke(yp, outLinkUrl));}
Java反射 二三事相关推荐
- Java学习之二-Java反射机制
问题: 在运行时,对一个JAVA类,能否知道属性和方法:能否调用它的任意方法? 答案是可以的,JAVA提供一种反射机制可以实现. 目录 什么是JAVA的反射机制 JDK中提供的Reflection A ...
- java反射快速入门(二)
上一遍博文 , 简单介绍java 反射的常用接口,本遍博文, 我会结合项目开发的实际例子讲解下 java反射的使用 现在有个需求, 要将一个对象转换成xml格式, 或者将一串xml转换一个对象, 这时 ...
- java 反射类成员_java 反射(二)类成员
在Java反射的包中定义一个接口java.lang.reflect.Member,它有三个实现类java.lang.reflect.Field, java.lang.reflect.Method, a ...
- 夯实Java基础(二十一)——Java反射机制
1.反射机制概述 Java反射机制是指程序在运行状态中,对于任何一个类,我们都能够知道这个类的所有属性和方法(包括private.protected等).对于任何一个对象,我们都能够对它的属性和方法进 ...
- Java安全(二) 反射
反射相关概念 反射是Java的特征之一,是一种间接操作目标对象的机制,核心是JVM在运行状态的时候才动态加载类,对于任意一个类都能够知道这个类所有的属性和方法,并且对于任意一个对象,都能够调用它的方法 ...
- Java反射面试总结(二)
为什么引入反射概念?反射机制的应用有哪些? 我们来看一下 Oracle 官方文档中对反射的描述: 从 Oracle 官方文档中可以看出,反射主要应用在以下几方面: 反射让开发人员可以通过外部类的全路径 ...
- java 获取 反射 方法 名_乐字节Java反射之一:反射概念与获取反射源头Class
一.Java反射机制概念 "程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言",如Python, Ruby是动态语言:显然C++,Java,C#不是动态语言,但是JAV ...
- Java反射(详述版)
一.什么是反射? 我们先来看一个例子: package venus; public class Student {public String name;public Student(){System. ...
- 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换
作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...
- Java反射机制分析指南
一.JAVA是动态语言吗? 一般而言,说到动态言,都是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言. 但JAVA它却有着一个非常突出的动态相关机制:反 ...
最新文章
- 【Xamarin挖墙脚系列:现有IPhone/IPad 设备尺寸】
- Sublime-text
- python3下载文件-python 3.3 下载固定链接文件并保存的方法
- 表贴电阻尺寸与什么有关_PCB板上为什么要“贴黄金”?
- 网络QoS的平衡之道——音视频弱网对抗策略介绍
- 斯坦福NLP组最新报告:自然语言处理中的学习挑战(附149页报告全文下载
- 用计算机表白的数字,用数字表白
- 数据库-mysql概述
- 转载:word排版之长英文单词自动换行
- 「镁客早报」小米“10亿赌约”输给格力;SpaceX本周将首次试飞新飞船...
- 看见几篇文章,收藏一下。
- LINUX SHELL中大小写转换及注意事项
- 维克多DBC文件结构
- 计算机右键管理快捷键,鼠标右键菜单管理
- 5053刷奥迪Q5隐藏功能
- 台式电脑开机显示蓝屏 检查计算机上的病毒,电脑出现蓝屏问题的诊断以及处理的方法...
- Python数据类型之三(列表)
- 微信退款通知显示乱码,xml解析中文乱码
- c语言求出现次数最多的字符,保证你看懂
- AWS DynamoDB基础使用
热门文章
- apple怎么其他_如何取消您的Apple Music(或任何其他)订阅
- document.querySelector()方法
- 农户在集市上卖西瓜,他总共有1020个西瓜,第一天卖掉一半多两个,第二天卖掉剩下的一半多两个, 问照此规律实下去,该农户几天能将所有的西瓜卖完。C语言
- MapReduce作业提交流程
- 谜一样的科学家——阿兰图灵
- 公有云上应该怎么做容灾?
- 公有云管理的一般建议
- 企业上云“行稳致远”,新钛云服“服务+产品”模式升级上云、用云新思维 | 爱分析洞见...
- 群体稳定度指标PSI
- Shell中的感叹号