文章1(侧重反射机制):
原文地址:http://blog.csdn.net/zhandoushi1982/article/details/8567709
Java中没有指针,不能传递方法函数的地址,一般采用接口回调实现。
(1)可以举个现实生活中的例子:一读者想借《软件技术学习与实践》这本书,但这本书已被其他读者借走了。于是,读者与图书馆管理员间发生了以下对话:
读者:“我把我的电话号码告诉你,等书一到就马上通知我。”
管理员:“好的。另一读者把书还回来后,马上给您打电话,书我先帮您留着。”
在上述这个场景中,读者就是“回调对象”,管理员就是“控制器对象”,读者的电话号码就是“回调对象的方法”。
(2)代码示例。
回调在JAVA中是通过接口和匿名内部类来实现的。匿名内部类的例子可参见onClickListener的用法,在形参中完成响应函数的过程。接口的用法可参见Camera.java (frameworks\base\core\java\Android\hardware)中的setPreviewCallback和takePicture函数,基本上是类似的。
======================================================================================================
反射机制的作用:
1,反编译:.class-->.java
2,通过反射机制访问java对象的属性,方法,构造方法等;下边我们具体看怎么实现这些功能
(1)反射机制获取类有三种方法,我们来获取Employee类型
- //第一种方式:
- Class c1 = Class.forName("Employee");
- //第二种方式:
- //java中每个类型都有class 属性.
- Class c2 = Employee.class;
- //第三种方式:
- //java语言中任何一个java对象都有getClass 方法
- Employee e = new Employee();
- Class c3 = e.getClass(); //c3是运行时类 (e的运行时类是Employee)
- Class c =Class.forName("Employee");
- //创建此Class 对象所表示的类的一个新实例
- Object o = c.newInstance(); //调用了Employee的无参数构造方法.
- public class main {
- public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, Exception{
- //获取整个类
- Class c = Class.forName("java.lang.Integer");
- //获取所有的属性?
- Field[] fs = c.getDeclaredFields();
- //定义可变长的字符串,用来存储属性
- StringBuffer sb = new StringBuffer();
- //通过追加的方法,将每个属性拼接到此字符串中
- //最外边的public定义
- sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() +"{\n");
- //里边的每一个属性
- for(int j = 0;j < fs.length;j++){
- sb.append("\t");//空格
- sb.append(Modifier.toString(fs[j].getModifiers())+" ");//获得属性的修饰符,例如public,static等等
- sb.append(fs[j].getType().getSimpleName() + " ");//属性的类型的名字
- sb.append(fs[j].getName()+";\n");//属性的名字+回车
- }
- sb.append("}");
- System.out.println(sb);
- }
- }
public final class Integer{
public static final int MIN_VALUE;
public static final int MAX_VALUE;
public static final Class TYPE;
static final char[] digits;
static final char[] DigitTens;
static final char[] DigitOnes;
static final int[] sizeTable;
private static String integerCacheHighPropValue;
private final int value;
public static final int SIZE;
private static final long serialVersionUID;
}
(4)再看获取特定的属性的写法:
- public class main {
- public void test(int x){
- System.out.println(x);
- }
- public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, Exception{
- /*
- Class<?> forName = Class.forName("main");
- Method method = forName.getDeclaredMethod("test", Integer.class);
- method.invoke(forName.newInstance(), 10);
- */
- Class<?> forName1 = Class.forName("main");
- Method method1 = forName1.getDeclaredMethod("test", int.class);
- method1.invoke(forName1.newInstance(), 10);
- }
- }
(5)获取方法,和构造方法,不再详细描述,只来看一下关键字:
这样我们就可以获得类的各种内容,进行了反编译。
文章2(侧重回调函数):
原文地址:http://blog.csdn.net/yehuang_0801/article/details/5648914
反射机制
- public class main {
- public void test(int x){
- System.out.println(x);
- }
- public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, Exception{
- /*
- Class<?> forName = Class.forName("main");
- Method method = forName.getDeclaredMethod("test", Integer.class);
- method.invoke(forName.newInstance(), 10);
- */
- Class<?> forName1 = Class.forName("main");
- Method method1 = forName1.getDeclaredMethod("test", int.class);
- method1.invoke(forName1.newInstance(), 10);
- }
- }
回调函数&函数回调&回调机制
所谓回调:就是A类中调用B类中的某个方法C,然后B类中反过来调用A类中的方法D,D这个方法就叫回调方法
- /**
- * 这是一个回调接口
- * @author xiaanming
- *
- */
- public interface CallBack {
- /**
- * 这个是小李知道答案时要调用的函数告诉小王,也就是回调函数
- * @param result 是答案
- */
- public void solve(String result);
- }
- /**
- * 这个是小王
- * @author xiaanming
- * 实现了一个回调接口CallBack,相当于----->背景一
- */
- public class Wang implements CallBack {
- /**
- * 小李对象的引用
- * 相当于----->背景二
- */
- private Li li;
- /**
- * 小王的构造方法,持有小李的引用
- * @param li
- */
- public Wang(Li li){
- this.li = li;
- }
- /**
- * 小王通过这个方法去问小李的问题
- * @param question 就是小王要问的问题,1 + 1 = ?
- */
- public void askQuestion(final String question){
- //这里用一个线程就是异步,
- new Thread(new Runnable() {
- @Override
- public void run() {
- /**
- * 小王调用小李中的方法,在这里注册回调接口
- * 这就相当于A类调用B的方法C
- */
- li.executeMessage(Wang.this, question);
- }
- }).start();
- //小网问完问题挂掉电话就去干其他的事情了,诳街去了
- play();
- }
- public void play(){
- System.out.println("我要逛街去了");
- }
- /**
- * 小李知道答案后调用此方法告诉小王,就是所谓的小王的回调方法
- */
- @Override
- public void solve(String result) {
- System.out.println("小李告诉小王的答案是--->" + result);
- }
- }
- /**
- * 测试类
- * @author xiaanming
- *
- */
- public class Test {
- public static void main(String[]args){
- /**
- * new 一个小李
- */
- Li li = new Li();
- /**
- * new 一个小王
- */
- Wang wang = new Wang(li);
- /**
- * 小王问小李问题
- */
- wang.askQuestion("1 + 1 = ?");
- }
- }
这个例子采用异步加回调
Java动态代理与反射详解
- import java.lang.reflect.*;
- public class Main {
- static void customer(ProxyInterface pi){
- pi.say();
- }
- public static void main(String[] args){
- RealObject real = new RealObject();
- ProxyInterface proxy = (ProxyInterface)Proxy.newProxyInstance(ProxyInterface.class.getClassLoader(),new Class[]{ProxyInterface.class}, new ProxyObject(real));
- customer(proxy);
- }
- }
- interface ProxyInterface{
- void say();
- }
- //被代理类
- class RealObject implements ProxyInterface{
- public void say(){
- System.out.println("i'm talking");
- }
- }
- //代理类,实现InvocationHandler 接口
- class ProxyObject implements InvocationHandler{
- private Object proxied = null;
- public ProxyObject(){
- }
- public ProxyObject(Object proxied){
- this.proxied = proxied;
- }
- public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
- System.out.println("hello");
- return arg1.invoke(proxied, arg2);
- };
- }
可以看到动态代理的代理类是实现了一个InvocationHandler的接口,我们通过reflect.Proxy的类的newProxyInstance方法就可以得到这个接口的实例,然后再来作为参数传递进去,这里每一个在代理类上处理的东西也会被重定向到调用处理器上。
至于动态代理和静态代理的区别,即动态代理是动态的创建代理和动态的处理方法的,这也是反射的一个重要体现之处。