我自己在开发的时候经常会用到反射,不需要引用jar,就可以调用系统的相关方法,所以自己总结了一下反射的用法。
首先是获取到class类
Class<?> testReflection= Class.forName("com.jueme.android.rtasr.TestReflection");
可以通过newInstance 来建立实例,这个方法不能传入参数,这里只能使用没有参数的public方法。如果这个实例是可以建立的,只是不能使用里面的成员,可以不用使用newInstance方法。
Object obj = testReflection.newInstance();
如果是private方法,
private TestReflection() {
}
则会报错
.TestReflection.<init>() is not accessible from java.lang.Class
一个类里面有变量,构造方法和方法。Class类中分别有方法取获取
testReflection.getFields();//获取所有的public变量
testReflection.getDeclaredFields();//获取所有的变量
testReflection.getField("name");//获取指定名字的public变量
testReflection.getDeclaredField("name"); //获取指定名字的变量
testReflection.getConstructors();//获取所有的public构造方法
testReflection.getMethods();//获取所有的public方法
显然加了Declared关键字就可以获取到所有的成员,所以在使用反射的时候一般都是使用带有Declared的方法,如果是public的方法,我们也不用使用调用。
建立一个测试的类,通过反射来拿到里面的变量和方法
public class TestReflection {
private static final String TAG = "TestReflection";
public String age;
private String name;
public TestReflection() {
}
private TestReflection(String age, String name) {
this.age = age;
this.name = name;
}
private void testMethod1(String test){
Log.d(TAG, "testMethod1: "+test);
}
public void testMethod2(){
Log.d(TAG, "testMethod2: ");
}
}
我们来调用一下testMethod1方法
try {
Class<?> testReflection= Class.forName("com.jueme.android.rtasr.TestReflection");
Constructor c=testReflection.getDeclaredConstructor(String.class,String.class);
c.setAccessible(true);
Object obj=c.newInstance("18","jueme");
Method testMethod1 = testReflection.getDeclaredMethod("testMethod1", String.class);
testMethod1.setAccessible(true);
testMethod1.invoke(obj, "aaaa");
} catch (Exception e) {
Log.d(TAG, "onCreate: "+e.toString());
e.printStackTrace();
}
注意这里调用了setAccessible方法,如果不调用的话会报错的
cannot access private method void
所以私有方法一定要调用这个方法。
invoke方法第一个参数一定是实例化的类。
接下来访问一下name这变量
try {
Class<?> testReflection= Class.forName("com.jueme.android.rtasr.TestReflection");
Constructor c=testReflection.getDeclaredConstructor(String.class,String.class);
c.setAccessible(true);
Object obj=c.newInstance("18","jueme");
Field name = testReflection.getDeclaredField("name");
name.setAccessible(true);
String nameStr = (String) name.get(obj);
} catch (Exception e) {
e.printStackTrace();
}