小孩正常身高揉哪个反射区长身高

您访问回复列表出错
您可以试试:北京哪家治疗遗尿症的医院好
来源:百度新闻源
台海网10月22日讯(海峡导报记者 李方芳 通讯员 练健萍)10年前,当时38岁的李再金成为中华骨髓库志愿者;10年后,已经48岁的李再金顺利地捐献了自己的造血干细胞,成为厦门年龄最大的捐献者。
  与家人商量后,本月16日,李再金前往福州肿瘤医院,20日无偿捐献出279毫升造血干细胞,成功挽救了上海一名30岁血液病女患者的生命。
  郡县安则天下治。21日,济南市政协召开“突破远郊县域经济”双月协商座谈会,委员专家汇聚一堂剖析济南县域发展薄弱问题,谋划未来发展路径。高新片区、西客站片区迅速崛起、南控规划获批……13年来,济南市“东拓、西进、南控、中疏”工作都有了实质性进展,委员专家们认为,到今日“北跨”工作仍须继续突破,建议推动黄河以北区域县域经济发展,改变城市东西狭长的格局,加密跨黄交通,取消城乡间高速收费,打通加快远郊县域经济发展的“最后一公里”。
  “2015年,章丘市地区生产总值是905亿元,超过平阴、济阳、商河三县总和,地方预算收入46.99亿元,超过平阴、济阳、商河的总和,远郊县域经济成为济南经济发展中明显的‘短板’,对全市经济总量的影响已经凸显。”座谈会上,济南市委党校经济管理教研部副主任、教授李金泉分析说。
  与发达地区、其他副省级城市或省会城市相比,济南县域经济薄弱,尤其是远郊县域经济发展的问题十分突出。2014年全省147个县区排名中,济南3县均排在70名开外:商河排141名,平阴排87名,济阳排76名。2015年全国百强县名单中济南只有章丘入围,排在第46位。
  从产业发展看,县域园区产业结构趋同现象严重,园区内企业之间产业关联度和相互渗透性很小。在济南已形成的42个县域性产业集群中,机械装备制造业有8个,交通装备制造和化工医药业分别有7个,重汽的生产厂区遍布多个县(市)区,产业结构雷同制约了产业配套能力的增强,也制约了产业集聚效用的发挥。
  济南市政协委员、济阳县政协主席杜爱君则建议,加快推动黄河以北区域县域经济发展,将“北跨”工作摆在更加突出位置加以推进。
  2003年6月,省委常委扩大会议原则上通过了济南的总体框架规划,确定了济南“东拓、西进、南控、北跨、中疏”的城市空间发展战略。他说,至今13年过去了,高新片区、西客站片区迅速崛起,《济南市南部山区保护与发展规划》批准实施,市委、市政府和中心城区众多大项目大量外迁,济南市“东拓、西进、南控、中疏”工作都有了实质性进展,仅有“北跨”工作仍然停留在“探讨”层面。
  从城市总体框架来看,东西90公里,南北最宽处只有十几公里。“这种狭长的带状空间致使交通半径、行政半径过大,这不仅大大增加了公共资源和公用设施的建设成本,也给广大市民的工作、生活造成了诸多不便,甚至在重金加强主城区交通设施建设的情况下,交通拥堵状况仍不能有效解决。相反,济南市黄河以北的济阳县区位优势明显、土地平坦宽满、人口密度适中、交通网络相对成熟,如果通过交通、产业、城建等方式跨河北来,既拉开了济南大发展的框架,拓展了济南大发展的空间,黄河以北县域经济突破也将迎刃而解。”在杜爱君看来,只有“北跨”顺畅了,才能抑制向南的冲动,保护好南部水源地和绿肺。
  为此,杜爱君建议市委、市政府尽快研究出台“北跨”建设的详细规划和发展战略,并将其作为全市重点事项纳入全市科学发展目标责任体系,组建专门班子,明确市直有关部门和有关区县的目标责任,积极向前推进。
  打通加快远郊县域经济发展的“最后一公里”,就必须在完善基础设施上做文章,成为与会委员专家们的共识。
  “以平阴为例,距离市区近100公里,融入省会的交通大通道虽然已经有了济菏高速、105国道和220国道,但仅就220国道来说,平阴段已经拓宽,但济南通往平阴的必经之路长清段却仍然较窄,这些都严重制约了平阴融入济南的步伐。商河、济阳等离市区虽不是太远,但由于黄河等天然屏障阻碍了北部对接,让投资者对到济南的心理距离仍然十分遥远。”济南市委党校经济管理教研部副主任李金泉教授说。
  济南市政协委员,济南禾宝中药材有限公司董事长刘孟建建议,取消城区到远郊县高速公路收费。“远郊县都已通高速,但实际利用率不高,根本原因还是收费问题。济南四个国道出口、黄河大桥、部分绕城高速收费问题已经解决,应该取消城乡间高速收费,使城乡间高速通畅起来。”他还建言尽快规划修建城区至远郊县(市)的城际轨道交通,彻底拉近城乡间距离,大幅降低城乡往返时间、交通成本。
  实施“北跨”,交通先行。济南市政协委员、济阳县政协主席杜爱君建议,进一步加强跨黄交通建设,建议在济南市沿黄范围内再规划建设3-4座大桥或隧道,增加跨河大桥密度。并结合当前正在建设的济石客专公铁大桥,尽快启动奥体中路北延工程,彻底将黄河变为城中河。他建议尽快启动轨道交通R3线延长线和城际铁路济南东-济阳-商河线、济阳-章丘线建设,打造连接主市区和黄河北部片区的快捷交通体系,拉动黄河以北片区县域经济发展。5580人阅读
【Android 插件化开发】(19)
【Android 基础】(145)
其实本来想加个前缀,结果标题是《Android 中反射还能这么用?》,后来想想,也不恰当,就把Android去了,本身反射是Java的东西,你硬生生的加个Android显然是不恰当的。
这几天稍微过了一下Weex的源码,可谓是亲眼目睹了它的源码。无意间发现一个类,叫WXHack,搜索一下代码,发现在Weex里用的地方就一处,好奇心驱使下去看了WXHack的源码,好家伙!看完之后总觉得这个类似曾相识,后来昨天在看OpenAtlas的代码的时候又看到了这个类,相关链接如下
后来我断定这个类应该是淘宝Atlas里的类,Weex直接抽出来了。为了验证自己的想法,下了个淘宝客户端反编译了下去找这个类,真的找到了。
想看源码的可以直接点上面的链接去看OpenAtals里的类,也可以看这个保持了淘宝的包结构,但是反编译并完全的项目,也就是包含了一些字节码的,但是这两个类应该是完整的。
那么携程的动态加载框架也算是有Atlas的成分了,自然也就有这两个类了,不出所料的找到了它们。
其实这个应该也不是淘专的专利,因为后来我在github上搜索了一番,发现了几个类似的类,这几个类在eclipse中竟然出现了。
那么,这两个类到底有什么作用呢,莫慌,容我慢慢道来。
首先,从名字上可以看出这是一个Hack类,它的作用就是辅助反射,但是它们却不是简简单单的辅助反射,而是反射后包装的形式:类,方法,字段 ,也就是HackedClass,HackedConstructor,HackedMethod,HackedField这几个反射的包装形式。并且还有AssertionFailureHandler用于处理反射发生异常时的处理,你可以选择扔出异常或者自己处理掉。
在看他的源码之前,我们先来看看传统的反射是怎么玩的。
写了两三个类用来测试。
Student实体类,内部有一个IBehavior类,代表学生的行为;此外还有静态变量,非静态变量,静态方法,非静态方法,泛型变量,作用就是等下测试不同场景的反射。
<pre class="prettyprint prettyprinted" data-original-code="public class Student implements Serializable {
private static String school = &清华大学&;
private HashMap scores = new HashMap();
private IBehavior behavior = new BehaviorImpl();
public Student() {
public Student(String name, int age) {
this.name =
this.age =
public IBehavior getBehavior() {
public void setBehavior(IBehavior behavior) {
this.behavior =
public void addScore(String name, int score) {
scores.put(name, score);
public HashMap getScores() {
public void setScores(HashMap scores) {
this.scores =
public String getName() {
public void setName(String name) {
this.name =
public int getAge() {
public void setAge(int age) {
this.age =
public static String getSchool() {
public static void setSchool(String school) {
Student.school =
public void say(String word) {
System.out.println(word);
public String toString() {
return &Student{& +
&school=& + school +
&, age=& + age +
&, name='& + name + '\'' +
&, scores=& + scores +
&, behavior=& + behavior +
" data-snippet-id="ext.ca8fa0209fec749c2b6697e" data-snippet-saved="false" data-codota-status="done">public class Student implements Serializable {
private static String school = "清华大学";
private int
private HashMap&String, Integer& scores = new HashMap&String, Integer&();
private IBehavior behavior = new BehaviorImpl();
public Student() {
public Student(String name, int age) {
this.name =
this.age =
public IBehavior getBehavior() {
public void setBehavior(IBehavior behavior) {
this.behavior =
public void addScore(String name, int score) {
scores.put(name, score);
public HashMap&String, Integer& getScores() {
public void setScores(HashMap&String, Integer& scores) {
this.scores =
public String getName() {
public void setName(String name) {
this.name =
public int getAge() {
public void setAge(int age) {
this.age =
public static String getSchool() {
public static void setSchool(String school) {
Student.school =
public void say(String word) {
System.out.println(word);
public String toString() {
return "Student{" +
"school=" + school +
", age=" + age +
", name='" + name + '\'' +
", scores=" + scores +
", behavior=" + behavior +
IBehavior接口以及其实现类的代码如下
public interface IBehavior {
void perform(String behaiviorName, String behaiviorContent);
public class BehaviorImpl implements IBehavior {
public void perform(String behaiviorName, String behaiviorContent) {
System.out.println("behaiviorName:" + behaiviorName);
System.out.println("behaiviorContent:" + behaiviorContent);
你要反射,就先得拿到Class对象,两种方式,一直是Class在你的项目中,可以直接引用,第二种就是这个Class可能你不能直接引用,比如Android中的ContextImpl,一般来说,第二种的使用场景会更广泛。
<pre class="prettyprint prettyprinted" data-original-code="//直接通过class
Class studentClassByClass = Student.
//通过class的字符串全类名
Class studentClassByName = Class.forName(&cn.edu.zafu.Student&);" data-snippet-id="ext.aea7f48882bccbd81825bcb" data-snippet-saved="false" data-codota-status="done">//直接通过class
Class&?& studentClassByClass = Student.
//通过class的字符串全类名
Class&?& studentClassByName = Class.forName("cn.edu.zafu.Student");
然后你可以直接调用class的newInstance方法新建一个对象,但是对于没有默认构造函数的类来说,你需要拿到构造函数再去新建对象。这里需要注意的是你不知道修饰符是private,protected,public中的哪一个时,建议调用setAccessible设置成true,不然极有可能会发生异常。
<pre class="prettyprint prettyprinted" data-original-code="//构造函数new对象
Constructor constructor = studentClassByName.getConstructor(String.class, int.class);
constructor.setAccessible(true);
Student student = (Student) constructor.newInstance(&区长&, 22);
System.out.println(student);" data-snippet-id="ext.4fa1e103a743ac05ae22d3" data-snippet-saved="false" data-codota-status="done">
Constructor&?& constructor = studentClassByName.getConstructor(String.class, int.class);
constructor.setAccessible(true);
Student student = (Student) constructor.newInstance("区长", 22);
System.out.println(student);
对于静态变量的访问,可以拿到Field,直接设置即可。set方法的第一个参数传null就是了。
//静态变量
Field schoolField = studentClassByName.getDeclaredField("school")
schoolField.setAccessible(true)
schoolField.set(null, "浙江大学")
System.out.println(Student.getSchool())
但是对于非静态变量,set方法的第一个参数你就需要传递一个实例进去,比如上面通过构造函数new出来的对象。
同理静态方法同静态变量
//静态方法调用
Method setSchoolMethod = studentClassByName.getDeclaredMethod("setSchool", String.class)
setSchoolMethod.invoke(null, "清华大学")
System.out.println(Student.getSchool())
非静态方法同非静态变量
//非静态方法调用
Method sayMethod = studentClassByName.getDeclaredMethod("say", String.class)
sayMethod.setAccessible(true)
sayMethod.invoke(student, "hello world")
等等,还有一个泛型变量呢
<pre class="prettyprint prettyprinted" data-original-code=" private HashMap scores = new HashMap();" data-snippet-id="ext.bedc64eb9121fe1ebb84b3c5cc452777" data-snippet-saved="false" data-codota-status="done"> private HashMap&String, Integer& scores = new HashMap&String, Integer&();
懵逼了,不会写。。。。。其实还是一样,强转就ok了,只不过强转前需要对类型进行校验。
然后就是异常处理,反射大多数人都是通过try catch直接捕捉异常。。。这也没什么好说的。
劫持,什么叫劫持呢,其实就是替换字段,有人说你直接反射拿到变量,直接反射替换就是了,这是一种方式,但是这并不是我想要的,比如我要劫持Student里的behavior变量,但是我不想修改它,我想保留它原来的逻辑,但是我又想加入新的东西,这个就有点类型面向切面编程了,比如日志的注入。怎么做?懵逼了。。。。显然是动态代理啊。使用代理类去完成劫持操作,既可以保留原有操作,又可以增加新的逻辑。
那么Hack类是怎么做的呢。首先生成HackedClass类,怎么生成的呢,调用Hack的into方法,入参有两种形式,一种就是直接传Class,另一种就是传递Class的全类名字符串。
<pre class="prettyprint prettyprinted" data-original-code="public static
HackedClass into(final Class clazz) {
return new HackedClass(clazz);
@SuppressWarnings({&rawtypes&, &unchecked&})
public static
HackedClass into(final String class_name) throws HackDeclaration.HackAssertionException {
return new HackedClass(Class.forName(class_name));
} catch (final ClassNotFoundException e) {
fail(new HackDeclaration.HackAssertionException(e));
return new HackedClass(null);
// TODO: Better solution to avoid null?
}" data-snippet-id="ext.5e91ff262e0e464adfe92360" data-snippet-saved="false" data-codota-status="done">public static &T& HackedClass&T& into(final Class&T& clazz) {
return new HackedClass&T&(clazz);
@SuppressWarnings({"rawtypes", "unchecked"})
public static &T& HackedClass&T& into(final String class_name) throws HackDeclaration.HackAssertionException {
return new HackedClass(Class.forName(class_name));
} catch (final ClassNotFoundException e) {
fail(new HackDeclaration.HackAssertionException(e));
return new HackedClass(null);
into方法返回的是HackedClass对象,这个对象是对反射的包装类之一。其源码如下
<pre class="prettyprint prettyprinted" data-original-code="public static class HackedClass {
protected Class mC
public HackedClass(final Class clazz) {
public HackedField staticField(final String name) throws HackDeclaration.HackAssertionException {
return new HackedField(mClass, name, Modifier.STATIC);
public HackedField field(final String name) throws HackDeclaration.HackAssertionException {
return new HackedField(mClass, name, 0);
public HackedMethod staticMethod(final String name, final Class... arg_types) throws HackDeclaration.HackAssertionException {
return new HackedMethod(mClass, name, arg_types, Modifier.STATIC);
public HackedMethod method(final String name, final Class... arg_types) throws HackDeclaration.HackAssertionException {
return new HackedMethod(mClass, name, arg_types, 0);
public HackedConstructor constructor(final Class... arg_types) throws HackDeclaration.HackAssertionException {
return new HackedConstructor(mClass, arg_types);
public Class getmClass() {
" data-snippet-id="ext.64cee6afb187f4390fafbabb" data-snippet-saved="false" data-codota-status="done">public static class HackedClass&C& {
protected Class&C& mC
public HackedClass(final Class&C& clazz) {
public HackedField&C, Object& staticField(final String name) throws HackDeclaration.HackAssertionException {
return new HackedField&C, Object&(mClass, name, Modifier.STATIC);
public HackedField&C, Object& field(final String name) throws HackDeclaration.HackAssertionException {
return new HackedField&C, Object&(mClass, name, 0);
public HackedMethod staticMethod(final String name, final Class&?&... arg_types) throws HackDeclaration.HackAssertionException {
return new HackedMethod(mClass, name, arg_types, Modifier.STATIC);
public HackedMethod method(final String name, final Class&?&... arg_types) throws HackDeclaration.HackAssertionException {
return new HackedMethod(mClass, name, arg_types, 0);
public HackedConstructor constructor(final Class&?&... arg_types) throws HackDeclaration.HackAssertionException {
return new HackedConstructor(mClass, arg_types);
public Class&C& getmClass() {
如果你要获得静态方法,就调用staticMethod,静态变量就调用staticField,非静态方法就调用method,非静态变量就调用field,要获得构造函数就调用constructor,当然你也可以调用getmClass获得Class。最终如果你调用方法相关的函数会得到HackedMethod,调用变量相关的会得到HackedField,调用构造函数相关的会获得HackedConstructor,这三个类的源码如下。自己看源码。。。。不解释了。。。太长了,主要是对反射的封装,并达到面向对象的效果。
<pre class="prettyprint prettyprinted" data-original-code="
public static class HackedField {
private final Field mF
HackedField(final Class clazz, final String name, int modifiers) throws HackDeclaration.HackAssertionException {
Field field =
if (clazz == null) {
field = clazz.getDeclaredField(name);
if (modifiers > 0 && (field.getModifiers() & modifiers) != modifiers) {
fail(new HackDeclaration.HackAssertionException(field + & does not match modifiers: & + modifiers));
field.setAccessible(true);
} catch (final NoSuchFieldException e) {
HackDeclaration.HackAssertionException hae = new HackDeclaration.HackAssertionException(e);
hae.setHackedClass(clazz);
hae.setHackedFieldName(name);
fail(hae);
} finally {
@SuppressWarnings(&unchecked&)
HackedField ofGenericType(final Class type) throws HackDeclaration.HackAssertionException {
if (mField != null && !type.isAssignableFrom(mField.getType())) {
fail(new HackDeclaration.HackAssertionException(new ClassCastException(mField + & is not of type & + type)));
return (HackedField)
@SuppressWarnings(&unchecked&)
public HackedField ofType(final String type_name) throws HackDeclaration.HackAssertionException {
return (HackedField) ofType(Class.forName(type_name));
} catch (final ClassNotFoundException e) {
fail(new HackDeclaration.HackAssertionException(e));
@SuppressWarnings(&unchecked&)
HackedField ofType(final Class type) throws HackDeclaration.HackAssertionException {
if (mField != null && !type.isAssignableFrom(mField.getType())) {
fail(new HackDeclaration.HackAssertionException(new ClassCastException(mField + & is not of type & + type)));
return (HackedField)
public void hijack(final C instance, final Interception.InterceptionHandler handler) {
final T delegatee = get(instance);
if (delegatee == null) {
throw new IllegalStateException(&Cannot hijack null&);
final Class[] interfaces = delegatee.getClass().getInterfaces();
set(instance, Interception.proxy(delegatee, handler, interfaces));
public T get(final C instance) {
@SuppressWarnings(&unchecked&) final T value = (T) mField.get(instance);
} catch (final IllegalAccessException e) {
e.printStackTrace();
public void set(final C instance, final Object value) {
mField.set(instance, value);
} catch (final IllegalAccessException e) {
e.printStackTrace();
public Field getField() {
public static class HackedMethod {
protected final Method mM
HackedMethod(final Class clazz, final String name, final Class[] arg_types, int modifiers) throws HackDeclaration.HackAssertionException {
Method method =
if (clazz == null) {
method = clazz.getDeclaredMethod(name, arg_types);
if (modifiers > 0 && (method.getModifiers() & modifiers) != modifiers) {
fail(new HackDeclaration.HackAssertionException(method + & does not match modifiers: & + modifiers));
method.setAccessible(true);
} catch (final NoSuchMethodException e) {
HackDeclaration.HackAssertionException hae = new HackDeclaration.HackAssertionException(e);
hae.setHackedClass(clazz);
hae.setHackedMethodName(name);
fail(hae);
} finally {
public Object invoke(final Object receiver, final Object... args) throws IllegalArgumentException, InvocationTargetException {
Object obj =
obj = mMethod.invoke(receiver, args);
} catch (final IllegalAccessException e) { /* Should never happen */
e.printStackTrace();
public Method getMethod() {
public static class HackedConstructor {
protected Constructor mC
HackedConstructor(final Class clazz, final Class[] arg_types) throws HackDeclaration.HackAssertionException {
if (clazz == null) {
mConstructor = clazz.getDeclaredConstructor(arg_types);
} catch (NoSuchMethodException e) {
HackDeclaration.HackAssertionException hae = new HackDeclaration.HackAssertionException(e);
hae.setHackedClass(clazz);
fail(hae);
public Object getInstance(final Object... arg_types) throws IllegalArgumentException {
Object obj =
mConstructor.setAccessible(true);
obj = mConstructor.newInstance(arg_types);
} catch (Exception e) {
e.printStackTrace();
}" data-snippet-id="ext.724d65da38a5c5049e8cf" data-snippet-saved="false" data-codota-status="done">
public static class HackedField&C, T& {
private final Field mF
HackedField(final Class&C& clazz, final String name, int modifiers) throws HackDeclaration.HackAssertionException {
Field field = null;
if (clazz == null) {
field = clazz.getDeclaredField(name);
if (modifiers & 0 && (field.getModifiers() & modifiers) != modifiers) {
fail(new HackDeclaration.HackAssertionException(field + " does not match modifiers: " + modifiers));
field.setAccessible(true);
} catch (final NoSuchFieldException e) {
HackDeclaration.HackAssertionException hae = new HackDeclaration.HackAssertionException(e);
hae.setHackedClass(clazz);
hae.setHackedFieldName(name);
fail(hae);
} finally {
@SuppressWarnings("unchecked")
public &T2& HackedField&C, T2& ofGenericType(final Class&?& type) throws HackDeclaration.HackAssertionException {
if (mField != null && !type.isAssignableFrom(mField.getType())) {
fail(new HackDeclaration.HackAssertionException(new ClassCastException(mField + " is not of type " + type)));
return (HackedField&C, T2&) this;
@SuppressWarnings("unchecked")
public HackedField&C, T& ofType(final String type_name) throws HackDeclaration.HackAssertionException {
return (HackedField&C, T&) ofType(Class.forName(type_name));
} catch (final ClassNotFoundException e) {
fail(new HackDeclaration.HackAssertionException(e));
return this;
@SuppressWarnings("unchecked")
public &T2& HackedField&C, T2& ofType(final Class&T2& type) throws HackDeclaration.HackAssertionException {
if (mField != null && !type.isAssignableFrom(mField.getType())) {
fail(new HackDeclaration.HackAssertionException(new ClassCastException(mField + " is not of type " + type)));
return (HackedField&C, T2&) this;
public void hijack(final C instance, final Interception.InterceptionHandler&?& handler) {
final T delegatee = get(instance);
if (delegatee == null) {
throw new IllegalStateException("Cannot hijack null");
final Class&?&[] interfaces = delegatee.getClass().getInterfaces();
set(instance, Interception.proxy(delegatee, handler, interfaces));
public T get(final C instance) {
@SuppressWarnings("unchecked") final T value = (T) mField.get(instance);
return value;
} catch (final IllegalAccessException e) {
e.printStackTrace();
return null;
public void set(final C instance, final Object value) {
mField.set(instance, value);
} catch (final IllegalAccessException e) {
e.printStackTrace();
public Field getField() {
public static class HackedMethod {
protected final Method mM
HackedMethod(final Class&?& clazz, final String name, final Class&?&[] arg_types, int modifiers) throws HackDeclaration.HackAssertionException {
Method method = null;
if (clazz == null) {
method = clazz.getDeclaredMethod(name, arg_types);
if (modifiers & 0 && (method.getModifiers() & modifiers) != modifiers) {
fail(new HackDeclaration.HackAssertionException(method + " does not match modifiers: " + modifiers));
method.setAccessible(true);
} catch (final NoSuchMethodException e) {
HackDeclaration.HackAssertionException hae = new HackDeclaration.HackAssertionException(e);
hae.setHackedClass(clazz);
hae.setHackedMethodName(name);
fail(hae);
} finally {
public Object invoke(final Object receiver, final Object... args) throws IllegalArgumentException, InvocationTargetException {
Object obj = null;
obj = mMethod.invoke(receiver, args);
} catch (final IllegalAccessException e) {
e.printStackTrace();
public Method getMethod() {
public static class HackedConstructor {
protected Constructor&?& mC
HackedConstructor(final Class&?& clazz, final Class&?&[] arg_types) throws HackDeclaration.HackAssertionException {
if (clazz == null) {
mConstructor = clazz.getDeclaredConstructor(arg_types);
} catch (NoSuchMethodException e) {
HackDeclaration.HackAssertionException hae = new HackDeclaration.HackAssertionException(e);
hae.setHackedClass(clazz);
fail(hae);
public Object getInstance(final Object... arg_types) throws IllegalArgumentException {
Object obj = null;
mConstructor.setAccessible(true);
obj = mConstructor.newInstance(arg_types);
} catch (Exception e) {
e.printStackTrace();
注意HackedField中有个方法叫hijack,这个方法的作用就是劫持。
最终,如果反射失败的话会进入Hack的fail方法处理,我们可以设置AssertionFailureHandler处理器,返回false会扔出异常,否则不会扔出异常。可以在里面做一些事,比如埋点。这样就可以集中到一个地方处理了。
private static void fail(HackDeclaration.HackAssertionException e) throws HackDeclaration.HackAssertionException {
if (sFailureHandler == null || !sFailureHandler.onAssertionFailure(e)) {
public static void setAssertionFailureHandler(AssertionFailureHandler handler) {
sFailureHandler =
public interface AssertionFailureHandler {
boolean onAssertionFailure(HackDeclaration.HackAssertionException failure);
瞎说了这么多,来实践一把。
获得HackedClass对象,调用Hack.into方法
<pre class="prettyprint prettyprinted" data-original-code="//通过Class来获得一个HackedClass
Hack.HackedClass hackPersonByClass = Hack.into(Student.class);
//输出class测试
System.out.println(hackPersonByClass.getmClass());
//通过Class的全类名获得一个HackedClass
Hack.HackedClass hackPersonByName = Hack.into(&cn.edu.zafu.Student&);
//输出class测试
System.out.println(hackPersonByName.getmClass());" data-snippet-id="ext.a40a5fbdf902acd5e58f" data-snippet-saved="false" data-codota-status="done">//通过Class来获得一个HackedClass
Hack.HackedClass&Student& hackPersonByClass = Hack.into(Student.class)
//输出class测试
System.out.println(hackPersonByClass.getmClass())
//通过Class的全类名获得一个HackedClass
Hack.HackedClass&Student& hackPersonByName = Hack.into("cn.edu.zafu.Student")
//输出class测试
System.out.println(hackPersonByName.getmClass())
创建实例,调用HackedClass的constructor方法,将参数的类型传入,然后调用getInstance方法就可以获得一个实例了。
Hack.HackedConstructor personConstructor = hackPersonByName.constructor(String.class, int.class);
Student student = (Student) personConstructor.getInstance("区长", 121);
System.out.println(student);
student.say("世界你好,世界再见");
非静态变量需要通过field方法获得一个HackedField对象,这时候你获得的field是一个Object类型的,因此如果你想要类型安全,需要调用一下ofType方法,将类型传入。
ofType 获得一个HackedField,非静态
Hack.HackedField hackName = hackPersonByName.field(&name&).ofType(String.class);
//反射调用
String name = hackName.get(student);
//输出结果测试
System.out.println(name);
//通过field -> ofType 获得一个HackedField,非静态
Hack.HackedField hackAge = hackPersonByName.field(&age&).ofType(int.class);
//反射设置属性
hackAge.set(student, 16);
//反射获得age,进行验证
Integer age = hackPersonByName.field(&age&).ofType(int.class).get(student);
//输出结果测试
System.out.println(age);" data-snippet-id="ext.fa9ebf69da14bbbf3a323e" data-snippet-saved="false" data-codota-status="done">//通过field -& ofType 获得一个HackedField,非静态
Hack.HackedField&Student, String& hackName = hackPersonByName.field("name").ofType(String.class)
//反射调用
String name = hackName.get(student)
//输出结果测试
System.out.println(name)
//通过field -& ofType 获得一个HackedField,非静态
Hack.HackedField&Student, Integer& hackAge = hackPersonByName.field("age").ofType(int.class)
//反射设置属性
hackAge.set(student, 16)
//反射获得age,进行验证
Integer age = hackPersonByName.field("age").ofType(int.class).get(student)
//输出结果测试
System.out.println(age)
静态变量直接调用staticField方法即可,除了上面的ofType将类型传入,这个类型可以是Class对象,也可以是Class字符串的全类名。
<pre class="prettyprint prettyprinted" data-original-code="
//反射获得静态变量
Hack.HackedField hackSchool = hackPersonByName.staticField(&school&).ofType(&java.lang.String&);
//获得静态变量值
String sSchool = (String) hackSchool.get(null);
//输出结果测试
System.out.println(sSchool);
hackSchool.getField().set(null, &北京大学&);
//获得值验证是否设置成功,通过getField()方式
sSchool = (String) hackSchool.getField().get(null);
//输出结果测试
System.out.println(sSchool);" data-snippet-id="ext.840950dfd42bf0f3cc12" data-snippet-saved="false" data-codota-status="done">
Hack.HackedField&Student, Object& hackSchool = hackPersonByName.staticField("school").ofType("java.lang.String");
String sSchool = (String) hackSchool.get(null);
System.out.println(sSchool);
hackSchool.getField().set(null, "北京大学");
sSchool = (String) hackSchool.getField().get(null);
System.out.println(sSchool);
泛型参数可以调用ofGenericType方法转为泛型,比如下面的Map
<pre class="prettyprint prettyprinted" data-original-code="//泛型参数
Hack.HackedField<Student, Map> hackScores = hackPersonByName.field(&scores&).ofGenericType(Map.class);
Map stringIntegerMap = hackScores.get(student);
stringIntegerMap.put(&语文&, 80);
stringIntegerMap.put(&数学&, 90);
//泛型参数设置
hackScores.set(student, stringIntegerMap);
//输出结果测试
System.out.println(student.getScores());" data-snippet-id="ext.1bacd8b861cd077a907e" data-snippet-saved="false" data-codota-status="done">//泛型参数
Hack.HackedField&Student, Map&String, Integer&& hackScores = hackPersonByName.field("scores").ofGenericType(Map.class)
Map&String, Integer& stringIntegerMap = hackScores.get(student)
stringIntegerMap.put("语文", 80)
stringIntegerMap.put("数学", 90)
//泛型参数设置
hackScores.set(student, stringIntegerMap)
//输出结果测试
System.out.println(student.getScores())
方法的调用需要调用method相关的方法,非静态方法直接调用method方法获得HackedMethod对象,需要将方法的参数类型传入。之后直接invoke调用的时候将调用对象实例和参数传入。
//反射非静态方法调用
hackPersonByName.method("say", String.class).invoke(student, "fuck the source code")
静态方法和非静态方法相比就是invoke的时候调用对象可以直接传null。
//反射静态方法调用
hackPersonByName.staticMethod("setSchool", String.class).invoke(null, "南京大学")
//输出结果测试
System.out.println(Student.getSchool())
//反射静态方法调用
String school = (String) hackPersonByName.staticMethod("getSchool").getMethod().invoke(null)
System.out.println(school)
以上调用的最终输出如下图所示,代码可能跟图有出入(貌似修改过前后顺序)
Hack类里的异常处理最终都会走到fail方法中,fail方法中会判断AssertionFailureHandler是否为空,空的情况下会直接扔出异常,否则会看AssertionFailureHandler的处理结果,如果结果返回true,则不扔出异常,返回fasle的情况下也会扔出异常,我们通过setAssertionFailureHandler方法设置一个异常处理器就可以了。下面调用两个不存在的字段,让它进入到这个处理器中,如果字段名是notHandler则扔出异常,否则输出信息并返回true。
<pre class="prettyprint prettyprinted" data-original-code="//异常处理
Hack.setAssertionFailureHandler(new Hack.AssertionFailureHandler() {
public boolean onAssertionFailure(Hack.HackDeclaration.HackAssertionException failure) {
//如果是notHandler字段,则不处理,即扔出异常,否则打印输出,不扔出异常
if (&notHandler&.equals(failure.getHackedFieldName())) {
Class hackedClass = failure.getHackedClass();
String hackedFieldName = failure.getHackedFieldName();
String hackedMethodName = failure.getHackedMethodName();
System.out.println(&=====onAssertionFailure start=====&);
System.out.println(&hackedClass:& + hackedClass);
System.out.println(&hackedFieldName:& + hackedFieldName);
System.out.println(&hackedMethodName:& + hackedMethodName);
System.out.println(&=====onAssertionFailure end=====&);
//返回true不会抛出异常,否则抛出异常
//获得一个不存在的对象,验证onAssertionFailure回调
Hack.HackedField unknownField = hackPersonByName.field(&unknownField&).ofType(String.class);
Hack.HackedField notHandler = hackPersonByName.field(&notHandler&).ofType(String.class);
" data-snippet-id="ext.9ecd6bd84d1b2ae87101f" data-snippet-saved="false" data-codota-status="done">//异常处理
Hack.setAssertionFailureHandler(new Hack.AssertionFailureHandler() {
public boolean onAssertionFailure(Hack.HackDeclaration.HackAssertionException failure) {
//如果是notHandler字段,则不处理,即扔出异常,否则打印输出,不扔出异常
if ("notHandler".equals(failure.getHackedFieldName())) {
return false
Class&?& hackedClass = failure.getHackedClass()
String hackedFieldName = failure.getHackedFieldName()
String hackedMethodName = failure.getHackedMethodName()
System.out.println("=====onAssertionFailure start=====")
System.out.println("hackedClass:" + hackedClass)
System.out.println("hackedFieldName:" + hackedFieldName)
System.out.println("hackedMethodName:" + hackedMethodName)
System.out.println("=====onAssertionFailure end=====")
//返回true不会抛出异常,否则抛出异常
return true
//获得一个不存在的对象,验证onAssertionFailure回调
Hack.HackedField&Student, String& unknownField = hackPersonByName.field("unknownField").ofType(String.class)
Hack.HackedField&Student, String& notHandler = hackPersonByName.field("notHandler").ofType(String.class)
最终的效果如下
劫持字段,字段的劫持就是通过动态代理来实现的,内部的逻辑如下
<pre class="prettyprint prettyprinted" data-original-code="public static abstract class InterceptionHandler implements
InvocationHandler {
private T mD
public Object invoke(Object obj, Method method, Object[] args)
throws Throwable {
Object obj2 =
obj2 = method.invoke(delegatee(), args);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e2) {
e2.printStackTrace();
} catch (InvocationTargetException e3) {
throw e3.getTargetException();
return obj2;
protected T delegatee() {
return this.mD
void setDelegatee(T t) {
this.mDelegatee =
}" data-snippet-id="ext.908e9f85ed" data-snippet-saved="false" data-codota-status="done">public static abstract class InterceptionHandler&T& implements
InvocationHandler {
private T mD
public Object invoke(Object obj, Method method, Object[] args)
throws Throwable {
Object obj2 = null;
obj2 = method.invoke(delegatee(), args);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e2) {
e2.printStackTrace();
} catch (InvocationTargetException e3) {
throw e3.getTargetException();
return obj2;
protected T delegatee() {
return this.mD
void setDelegatee(T t) {
this.mDelegatee =
这个字段的方法调用都是调用委托对象,这个对象就是我们原始的字段,这个delegatee方法我们可以重写返回新对象,这样就和反射直接替换没有什么差别了。当然也可以重写invoke方法,在调用前和调用后做一些处理。比如我做一些日志输出。如下代码
<pre class="prettyprint prettyprinted" data-original-code="//字段劫持处理
Interception.InterceptionHandler handler = new Interception.InterceptionHandler() {
public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
System.out.println(&hijack:[invoke start]&);
Object o = super.invoke(obj, method, args);
System.out.println(&hijack:[invoke end]&);
//劫持behavior字段
hackPersonByName.field(&behavior&).hijack(student, handler);
//测试劫持效果
student.getBehavior().perform(&sleep&, &sleep 10h&);" data-snippet-id="ext.36945d5edf969058baa6" data-snippet-saved="false" data-codota-status="done">
Interception.InterceptionHandler handler = new Interception.InterceptionHandler&IBehavior&() {
public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
System.out.println("hijack:[invoke start]");
Object o = super.invoke(obj, method, args);
System.out.println("hijack:[invoke end]");
hackPersonByName.field("behavior").hijack(student, handler);
student.getBehavior().perform("sleep", "sleep 10h");
最终效果如下
好了说了这么多,还是不明白这个东西有什么软用呢?Android动态加载资源的时候我们需要用到的ContextImpl对象,需要对AssetManager和Resources需要做一些操作,就可以这么来了。
<pre class="prettyprint prettyprinted" data-original-code="
import java.lang.reflect.InvocationTargetE
public class Hacks extends HackDeclaration implements
AssertionFailureHandler {
public static HackedClass AssetM
public static HackedMethod AssetManager_addAssetP
public static HackedClass ContextI
public static HackedField ContextImpl_mR
public static boolean sIsReflectC
public static boolean sIsReflectA
public static boolean defineAndVerify() {
if (sIsReflectChecked) {
return sIsReflectA
Hacks hacks = new Hacks();
Hack.setAssertionFailureHandler(hacks);
allClasses();
allConstructors();
allFields();
allMethods();
sIsReflectAvailable =
return sIsReflectA
} catch (Throwable e) {
e.printStackTrace();
} finally {
Hack.setAssertionFailureHandler(null);
sIsReflectChecked =
private static void allClasses() throws HackAssertionException {
AssetManager = Hack.into(AssetManager.class);
ContextImpl = Hack.into(&android.app.ContextImpl&);
private static void allConstructors() throws HackAssertionException {
private static void allFields() throws HackAssertionException {
ContextImpl_mResources = ContextImpl.field(&mResources&).ofType(
Resources.class);
private static void allMethods() throws HackAssertionException {
AssetManager_addAssetPath = AssetManager.method(&addAssetPath&, String.class);
public boolean onAssertionFailure(HackAssertionException hackAssertionException) {
//throw it
}" data-snippet-id="ext.761aabe2bd8cbaa0a5b4f3f" data-snippet-saved="false" data-codota-status="done">
import java.lang.reflect.InvocationTargetE
public class Hacks extends HackDeclaration implements
AssertionFailureHandler {
public static HackedClass&AssetManager& AssetM
public static HackedMethod AssetManager_addAssetP
public static HackedClass&Object& ContextI
public static HackedField&Object, Resources& ContextImpl_mR
public static boolean sIsReflectC
public static boolean sIsReflectA
public static boolean defineAndVerify() {
if (sIsReflectChecked) {
return sIsReflectA
Hacks hacks = new Hacks();
Hack.setAssertionFailureHandler(hacks);
allClasses();
allConstructors();
allFields();
allMethods();
sIsReflectAvailable = true;
return sIsReflectA
} catch (Throwable e) {
e.printStackTrace();
} finally {
Hack.setAssertionFailureHandler(null);
sIsReflectChecked = true;
return false;
private static void allClasses() throws HackAssertionException {
AssetManager = Hack.into(AssetManager.class);
ContextImpl = Hack.into("android.app.ContextImpl");
private static void allConstructors() throws HackAssertionException {
private static void allFields() throws HackAssertionException {
ContextImpl_mResources = ContextImpl.field("mResources").ofType(
Resources.class);
private static void allMethods() throws HackAssertionException {
AssetManager_addAssetPath = AssetManager.method("addAssetPath", String.class);
public boolean onAssertionFailure(HackAssertionException hackAssertionException) {
return false;
调用 Hacks.defineAndVerify反复进行定义和验证,成功后就可以直接调用了。
boolean flag = Hacks.defineAndVerify()
if (flag) {
AssetManager assetManager = AssetManager.class.newInstance()
Hacks.AssetManager_addAssetPath.invoke(assetManager,"assetPath")
Hacks.ContextImpl_mResources.set(context, resources)
上面的这个例子是伪代码,实际情况自己去把握~~~~写的比较随意,看看就好了~
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:496430次
积分:7339
积分:7339
排名:第2098名
原创:160篇
评论:563条
阅读:40522
阅读:12958
阅读:57958
阅读:16428
阅读:23961

我要回帖

更多关于 小孩身高体重标准表 的文章

 

随机推荐