为什么要学反射
因为当你要Hook方法的时候就必须用到反射
如何获取一个类
String str1="abc";
//第一种方式:用类名.class
Class class1=String.class;
//第二种方式:用String的对象获取String的字节码
Class class2=str1.getClass();
//第二种方式:用String的对象获取String的字节码
Class class3=Class.forName("java.lang.String");
System.out.println("结果如下");
System.out.println(class1==class2);
System.out.println(class1==class3);
这个类的结果输出是两个true,说明每个类的字节码,在内存中只有一份,无论你用三种方式的哪一种方式去取,得到的都是同一份字节码。
Filed,Method 简单使用
直接上代码
private void testFiled(){
//获取String的length方法
String a = "adc";
try {
//获取类
Class StringClass = Class.forName("java.lang.String");
Field fieldCount = StringClass.getDeclaredField("count"); //public 用getField
fieldCount.setAccessible(true); //暴力反射
int count = (int)fieldCount.get(a); //获取count数值
Log.e("MainActivity", "count " + count);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
Method
private void testMethod(){
try {
String a = "abc";
Class StringClass = Class.forName("java.lang.String");
//根据类名获取方法, 如果
Method lengthMethod = StringClass.getMethod("length");
//得到方法之后,调用对象str的length方法;
int result = (int) lengthMethod.invoke(a);
Log.e("MainActivity", "length " + result);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
Proxy 动态代理
Proxy用来在实际对象中加上自己想要加上的料。 在动态代理上所做的所有调用都会被重定向到单一的调用处理器上,它的工作是揭示调用的类型并确定相应的策略。以下是一个动态代理示例:
下面的例子是网上找的。
1.接口和实现类:
public interface Interface {
void doSomething();
void somethingElse(String arg);
}
public class RealObject implements Interface {
public void doSomething() {
System.out.println("doSomething.");
}
public void somethingElse(String arg) {
System.out.println("somethingElse " + arg);
}
}
2.动态代理对象处理器:
public class DynamicProxyHandler implements InvocationHandler {
private Object proxyed;
public DynamicProxyHandler(Object proxyed) {
this.proxyed = proxyed;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
System.out.println("代理工作了.");
return method.invoke(proxyed, args);
}
}
3.测试类:
public class Main {
public static void main(String[] args) {
RealObject real = new RealObject();
//替换掉了原来的方法
Interface proxy = (Interface) Proxy.newProxyInstance(
Interface.class.getClassLoader(), new Class[] {Interface.class},
new DynamicProxyHandler(real));
proxy.doSomething();
proxy.somethingElse("luoxn28");
}
}
其他文章:
写个Hook例子练练手