Android 注解和反射原理和实现学习(下)
来源:互联网 发布:淘宝内部优惠卷怎么做 编辑:程序博客网 时间:2024/03/29 01:05
如何调用类中的private方法
1.创建一个类的实例
在得到一个类的Class对象之后,我们可以利用类Constructor去实例化该对象。Constructor支持泛型,也就是它本身应该是Constructor<T>。这个类有一个public成员函数:T newInstance(Object... args),其中args为对应的参数,我们通过Constructor的这个方法来创建类的对象实例。实例Class类的方法有两种,一种是利用Constructor类调用newInstance()方法,另一种就是利用Class类本身的newInstance()方法创建一个实例,构造函数无参数两种方法实现的效果是一样的。如果构造函数有多个,那就不一样了,不同的构造函数创建的对象不一样。
// 加载指定的类Class<?> clazz = Class.forName(cName); // 利用newInstance()方法,获取构造方法的实例// Class的newInstance方法只提供默认无参构造实例// Constructor的newInstance方法提供带参的构造实例Constructor<?> constructor = clazz.getConstructor();Object obj = constructor.newInstance(); //如果是无参数的构造函数创建实例,用这个方法简单一些//Object obj = clazz.newInstance();
2.行为(执行)
Method类中包含着类的成员方法的信息。在Method类中有一个public成员函数:Object invoke(Object receiver, Object... args),参数receiver指明了调用对象,参数args指明了该方法所需要接收的参数。由于我们是在运行时动态的调用类的方法,无法提前知道该类的参数类型和返回值类型,所以传入的参数的类型是Object,返回的类型也是Object。如果某一个方法是Java类的静态方法,那么Object receiver参数可以传入null,因为静态方法从不属于对象。
3.属性
对类的成员变量进行读写,在Field类中有两个public方法:Object get(Object object),该方法可用于获取某成员变量的值;Void set(Object object, Object value),该方法设置某成员变量的值。其中,Object参数是需要传入的对象;如果成员变量是静态属性,在object可传入null。
//获取和设置属性值 Field field = clazz.getField("i"); field.setAccessible(true); Object obj = clazz.newInstance(); Object valuen = field.get(obj); field.set(obj,2);整个的代码
//获取Class对象 String className = "com.kayak.annotationdemo.E"; Class<?> clazz = Class.forName(className); //获取到无参数的构造方法 Constructor<?> constructor = clazz.getConstructor(); //创建实例 Object object = constructor.newInstance(); Class<?>[] parameterTypes = new Class<?>[]{String.class,Context.class}; //获取指定的方法 Method method = clazz.getDeclaredMethod("mtest",parameterTypes); method.setAccessible(true); Object[] values = new Object[]{"md",this}; method.invoke(object,values);
LoadMethod.java的优化处理代码
import java.lang.reflect.Constructor;import java.lang.reflect.Method;public class LoadMethodEx { /** * 在运行时加载指定的类,并调用指定的方法 * @param cName Java的类名 * @param MethodName 方法名 * @param params 方法的参数值 * @return */ public Object Load(String cName, String MethodName, Object[] params) { Object retObject = null; try { // 加载指定的类 Class<?> clazz = Class.forName(cName); // 利用newInstance()方法,获取构造方法的实例 // Class的newInstance方法只提供默认无参构造实例 // Constructor的newInstance方法提供带参的构造实例 Constructor<?> ct = clazz.getConstructor(); Object obj = ct.newInstance(); // 根据方法名获取指定方法的参数类型列表 Class<?> paramTypes[] = this.getParamTypes(clazz, MethodName); // 获取指定方法 Method meth = clazz.getMethod(MethodName, paramTypes); meth.setAccessible(true); // 调用指定的方法并获取返回值为Object类型 retObject = meth.invoke(obj, params); } catch (Exception e) { System.err.println(e); } return retObject; } /***获取参数类型,返回值保存在Class[]中*/ private Class<?>[] getParamTypes(Class<?> cls, String mName) { Class<?>[] clazz = null; /**Note: 由于我们一般通过反射机制调用的方法,是非public方法 * 所以在此处使用了getDeclaredMethods()方法*/ Method[] mtd = cls.getDeclaredMethods(); for (int i = 0; i < mtd.length; i++) { if (!mtd[i].getName().equals(mName)) { // 不是我们需要的参数,则进入下一次循环 continue; } clazz = mtd[i].getParameterTypes(); } return clazz; }}
参考文章:利用java反射技术阻止通过按钮关闭对话框连接:点击打开链接
下面添上一段利用java反射技术阻止通过按钮关闭对话框的代码
package crazypebble.androidreflection;import java.lang.reflect.Field;import android.app.Activity;import android.app.AlertDialog;import android.content.DialogInterface;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity { /** Called when the activity is first created. */ private static Button btnHandler = null; private static Button btnShowing = null; AlertDialog alertDialog = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btnHandler = (Button)findViewById(R.id.btn_mHandler); btnHandler.setOnClickListener(new ButtonListener()); btnShowing = (Button)findViewById(R.id.btn_mShowing); btnShowing.setOnClickListener(new ButtonListener()); alertDialog = new AlertDialog.Builder(this) .setTitle("abc") .setMessage("Content") .setIcon(R.drawable.icon) .setPositiveButton("确定", new PositiveClickListener()) .setNegativeButton("取消", new NegativeClickListener()) .create(); } private class ButtonListener implements OnClickListener { @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_mHandler: modify_mHandler(); alertDialog.show(); break; case R.id.btn_mShowing: alertDialog.show(); break; default: break; } } } private class PositiveClickListener implements android.content.DialogInterface.OnClickListener { @Override public void onClick(DialogInterface dialog, int which) { // 方法二时启用 modify_dismissDialog(false); } } private class NegativeClickListener implements android.content.DialogInterface.OnClickListener { @Override public void onClick(DialogInterface dialog, int which) { // 方法一时启用 //dialog.dismiss(); // 方法二时启用 modify_dismissDialog(true); } } /* * 第一种方法:修改AlertController类的private成员变量mHandler的值 */ public void modify_mHandler() { try { Field field = alertDialog.getClass().getDeclaredField("mAlert"); field.setAccessible(true); // 获取mAlert变量的值 Object obj = field.get(alertDialog); field = obj.getClass().getDeclaredField("mHandler"); field.setAccessible(true); // 修改mHandler变量的值,使用新的ButtonHandler类 field.set(obj, new MyButtonHandler(alertDialog)); } catch (Exception e) { e.printStackTrace(); } } /* * 第二种方法:修改dismissDialog()方法 */ public void modify_dismissDialog(boolean flag) { try { Field field = alertDialog.getClass().getSuperclass().getDeclaredField("mShowing"); field.setAccessible(true); // 将mShowing变量设为false,表示对话框已经关闭 field.set(alertDialog, flag); alertDialog.dismiss(); } catch (Exception e) { e.printStackTrace(); } }}
package crazypebble.androidreflection;import java.lang.ref.WeakReference;import android.content.DialogInterface;import android.os.Handler;import android.os.Message;public class MyButtonHandler extends Handler{ // Button clicks have Message.what as the BUTTON{1,2,3} constant private static final int MSG_DISMISS_DIALOG = 1; private WeakReference<DialogInterface> mDialog; public MyButtonHandler(DialogInterface dialog) { mDialog = new WeakReference<DialogInterface>(dialog); } @Override public void handleMessage(Message msg) { switch (msg.what) { case DialogInterface.BUTTON_POSITIVE: case DialogInterface.BUTTON_NEGATIVE: case DialogInterface.BUTTON_NEUTRAL: ((DialogInterface.OnClickListener) msg.obj).onClick(mDialog.get(), msg.what); break; } }}
反射机制通过void setAccessible(boolean flag)方法可以得到一个类的private的方法和属性,使用这些private的方法和属性,已经可以做一些超越限制的事情了,从而也面临了一些安全性的问题。
0 0
- Android 注解和反射原理和实现学习(下)
- Android 注解和反射原理和实现学习(上)
- android 注解和反射
- android的反射和注解
- Android中用注解和反射实现控件的绑定
- Java学习之反射和注解
- java反射机制和自定义注解原理分析和实例
- Android通过反射和注解简化代码编写(一)
- 通过注解和反射编写一个android注解框架
- java反射和注解
- 注解和反射
- java反射和注解
- 反射和注解
- Java注解和反射
- 反射和注解
- 反射和注解
- Java反射学习总结终(使用反射和注解模拟JUnit单元测试框架)
- 用spring mvc框架的模拟实现来学习反射和注解
- tableView的上拉刷新和下拉刷新
- 《Pro Git》笔记四:分布式工作流程
- hbase 继承RestFul问题
- SQL 数据库里是否可以通过视图更改表中的数据?
- apache 编译错误 configure: error: APR not found
- Android 注解和反射原理和实现学习(下)
- js contains方法
- xterm run command
- CF#309(Div2)C(组合数的数学题)
- cmake的一些小经验
- js中cookie的使用详细分析
- 查看安卓应用包名
- richedit插入图片错误
- ssh学习路线