概要
反射就是能够根据你给出类名实例化出一个实实在在的对象。所以,对象的实例化就不是写死的了,我们可以根据传入的类名不同,从而可以实例化出不同的对象。这种方式可以和工厂设计模式很好的结合,从而可以更加灵活的创建对象
测试用例
定义一个类
定义一个类,用反射来调用他的成员,方法,构造函数等
package com.example.xuyushi.reflecttest;
import android.util.Log;
/**
* Created by xuyushi on 15/7/14.
*/
public class student {
static final String TAG = "student";
private int age;
private String name;
private String addresss;
public student() {
Log.d(TAG, "none parameter student constructor");
}
public student(int age, String name, String addresss) {
this.age = age;
this.name = name;
this.addresss = addresss;
Log.d(TAG, "3 parameters student constructor");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddresss() {
return addresss;
}
public void setAddresss(String addresss) {
this.addresss = addresss;
}
@Override
public String toString() {
return super.toString();
}
public void printMessage(int age,String name,String adress){
Log.d(TAG, "name=" + name + ",age=" + age + ",adress=" + adress);
}
}
测试用例
public class MainActivity extends Activity {
static final String TAG = "student";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testReflect();
}
private void testReflect() {
try {
/**
* 1 反射出无参的构造方法并得到对象
* 注意:
* 1 在Class.forName()中应该传入含有包名的类全名
* 2 newInstance()方法的本质是调用类的无参Public构造方法
*/
String className1="com.example.xuyushi.reflecttest.student";
Class clazz1=Class.forName(className1);
Object object1=clazz1.newInstance();
/**
* 2 反射出带参数的构造方法并得到对象
*/
String className2="com.example.xuyushi.reflecttest.student";
Class clazz2=Class.forName(className2);
Constructor constructor1=clazz2.getConstructor(int.class,String.class,String.class);
Object object2=constructor1.newInstance(18,"zhangsan","beijing");
Log.d(TAG, object2.toString());
/**
* 3 获取类的私有字段
* 注意:
* 获取共有字段应调用clazz3.getField(name)方法
*/
String className3="com.example.xuyushi.reflecttest.student";
Class clazz3=Class.forName(className3);
Field ageField1=clazz3.getDeclaredField("age");
Log.d(TAG,"ageField1=" + ageField1);
/**
* 4 获取和更改某个对象的私有字段
* 即模拟get()和set()方法
*/
String className4="com.example.xuyushi.reflecttest.student";
Class clazz4=Class.forName(className4);
Field ageField2=clazz4.getDeclaredField("age");
Object object4=constructor1.newInstance(19,"wangwu","shanghai");
//取消访问私有字段的合法性检查
ageField2.setAccessible(true);
//获取对象的私有字段
Object ageObject4=ageField2.get(object4);
Log.d(TAG, "ageObject4=" + ageObject4);
//再更改对象的私有字段的值
ageField2.set(object4, 27);
//重新获得
Object ageObject5=ageField2.get(object4);
Log.d(TAG, "ageObject5=" + ageObject5);
/**
* 5 调用对象的带参数的方法
*/
String className5="com.example.xuyushi.reflecttest.student";
Class clazz5=Class.forName(className5);
Method method=clazz5.getMethod("printMessage",int.class,String.class,String.class);
Object object5=clazz5.newInstance();
method.invoke(object5,50, "lisi","hangzhou");
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
实际用例
开关移动流量需要用到sdk中的隐藏函数,需要利用到反射机制实现
public void toggleMobileData(Context context, boolean enabled) {
ConnectivityManager conMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Class<?> conMgrClass = null; // ConnectivityManager类
Field iConMgrField = null; // ConnectivityManager类中的字段
Object iConMgr = null; // IConnectivityManager类的引用
Class<?> iConMgrClass = null; // IConnectivityManager类
Method setMobileDataEnabledMethod = null; // setMobileDataEnabled方法
try {
// 取得ConnectivityManager类
conMgrClass = Class.forName(conMgr.getClass().getName());
// 取得ConnectivityManager类中的对象mService
iConMgrField = conMgrClass.getDeclaredField("mService");
// 设置mService可访问
iConMgrField.setAccessible(true);
// 取得mService的实例化类IConnectivityManager
iConMgr = iConMgrField.get(conMgr);
// 取得IConnectivityManager类
iConMgrClass = Class.forName(iConMgr.getClass().getName());
// 取得IConnectivityManager类中的setMobileDataEnabled(boolean)方法
setMobileDataEnabledMethod = iConMgrClass.getDeclaredMethod("setMobileDataEnabled", Boolean.TYPE);
// 设置setMobileDataEnabled方法可访问
setMobileDataEnabledMethod.setAccessible(true);
// 调用setMobileDataEnabled方法
setMobileDataEnabledMethod.invoke(iConMgr, enabled);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}