java中的反射机制:只要给定类的名字就可以得到所有类的信息。因为这个类的名字是可以在代码运行时动态指定的,所以利用java的反射机制比通过new的方式要灵活的多 在java中,通过new的方式创建的对象称为静态加载(编译时加载类),通过反射机制创建对象称为动态加载(运行时加载类) java反射机制的使用方式 这里有个Human类如下 package com.myway5; public class Human { private String name; private int age; public String word;
public Human() {
// TODO Auto-generated constructor stub
}
public Human(String name) {
this.name = name;
}
public Human(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void speak(String word) {
System.out.println(word);
}
} 我们使用反射机制获取Human类所有的信息 package com.myway5; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Client { public static void main(String[] args) { // 获取类名等信息 Class class1 = Human.class; System.out.println(class1.getName()); System.out.println(class1.getSimpleName());
System.out.println("***********构造方法**********");
Constructor[] cs = class1.getDeclaredConstructors();
for (Constructor constructor : cs) {
System.out.print(constructor.getName() + "(");
Class[] paramsType = constructor.getParameterTypes();
for (Class class2 : paramsType) {
System.out.print(class2.getName() + ",");
}
System.out.println(")");
}
System.out.println("**********公共成员变量************");
Field[] fields = class1.getFields();
for (Field field : fields) {
System.out.println(field.getType().getName() + ":" + field.getName());
}
System.out.println("**********公共方法**************");
Method[] methods = class1.getMethods();
for (Method method : methods) {
System.out.print(method.getName() + "(");
Class[] params = method.getParameterTypes();
for (Class class3 : params) {
System.out.print(class3.getName() + ",");
}
System.out.println(method.getReturnType().getName() + ")");
}
}
} 输出结果如下: com.myway5.Human Human ***********构造方法********** com.myway5.Human(java.lang.String,int,) com.myway5.Human(java.lang.String,) com.myway5.Human() **********公共成员变量************ java.lang.String:word **********公共方法************** getName(java.lang.String) setName(java.lang.String,void) getAge(int) setAge(int,void) wait(long,int,void) wait(long,void) wait(void) equals(java.lang.Object,boolean) toString(java.lang.String) hashCode(int) getClass(java.lang.Class) notify(void) notifyAll(void)
可以看到,所有公共的成员变量,方法都可以通过这个方式获取到,那么怎么调用其中的方法呢 public static void useMethod() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchMethodException, SecurityException { Class class1 = Human.class; Human man = (Human) class1.newInstance();//通过newInstance创建实例 Method method = class1.getMethod(“speak”, String.class); Object object = method.invoke(man, new Object[] { “hello reflect” }); } android开发中的使用后续更新 继上文更新: android开发中常常会使用java的反射机制来更改一些系统底层无法更改的代码逻辑。比如说在AlertDialog的使用中,通过自带的setPositiveButton或者setNegativeButton时,一旦点击按钮都会退出dialog,有时候我们不希望他退出,比如用户登录时登录失败再次登录。那么一种解决办法 就是通过java的反射机制。 package com.myway5.java_reflect; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import java.lang.ref.WeakReference; import java.lang.reflect.Field; public class MainActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AlertDialog.Builder builder=new AlertDialog.Builder(this);
builder.setMessage("Hello Dialog")
.setTitle("对话框")
.setView(getLayoutInflater().inflate(R.layout.dialog_signin,null));
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
AlertDialog dialog=builder.create();
try {
Field field = dialog.getClass().getDeclaredField("mAlert");
field.setAccessible(true);
Object obj=field.get(dialog);
field=obj.getClass().getDeclaredField("mHandler");
field.setAccessible(true);
field.set(obj,new ButtonHandler(dialog));
}catch (Exception e){
e.printStackTrace();
}
dialog.show();
}
private static final class ButtonHandler 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 ButtonHandler(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;
case MSG_DISMISS_DIALOG:
//这里是点击后的逻辑,因为注释掉了dismiss(),dialog不会退出了
//((DialogInterface) msg.obj).dismiss();
}
}
}
} 其中 try { Field field = dialog.getClass().getDeclaredField(“mAlert”); field.setAccessible(true); Object obj=field.get(dialog); field=obj.getClass().getDeclaredField(“mHandler”); field.setAccessible(true); field.set(obj,new ButtonHandler(dialog)); }catch (Exception e){ e.printStackTrace(); } 这个部分就是通过反射获取AlertDialog的私有变量mAlert,然后获取mAlert的成员变量mHandler,将这个Handler设置成我们自己的ButtonHandler,这样就解决了点击后退出的问题 代码地址:https://github.com/joyme123/java\_reflect 参考文章:http://www.oschina.net/question/163910\_27112