您的位置:首页 > 编程语言 > Java开发

java的反射机制笔记

2018-01-22 00:10 197 查看
java的反射机制笔记

首先了解什么是反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

JAVA反射(放射)机制:“程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言。但是JAVA有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。

通过以上的信息,我们可以猜测下,我们平时所做的应用所接的第三方的sdk,经常会让我们在自己的报名下放置相关的java类,可以添加自己的逻辑,这边应该也是用到了反射的机制,下面一起探索吧^_^,看看反射机制的作用。

这边有篇写的关于import语句的文章,写的不错http://zhaohe162.blog.163.com/blog/static/3821679720101120104444895/

1.相关操作定义

方法名

含义

getDeclaredFields()

获取类包含的全部变量,返回Field[]

getDeclaredFields(String name)

获取传入制定的的变量名的变量Field

getDeclaredMethods()

获取当前类的所有方法method[]

getDeclaredMethod(String name )

获取当前的name的方法

getDeclaredMethod(String name ,class[] …)

获取当前的name和参数class的方法

getReturnType()

获取方法的返回值类型

getParameterTypes()

获取方法的出入参数

getDeclaredConstructors()

获取当前类的构造方法

getDeclaredConstructor(class[],…)

获取带参数的构造方法

getSuperclass()

获取父类

getInterfaces()

获取当前类实现的接口

2.实现获取类的相关变量

先定义一个非常简单的Utils类

public class Utils {
public static String a = "a";
private String b = "b";
protected boolean c = false;

public String getA(){
Log.i("lz","lz do getA =" + a);
return a;
}
public static  String getAS(){
Log.i("lz","lz do getAS =" + a);
return a;
}
private String getB(){
Log.i("lz","lz do getB =" + b);
return b;
}
public boolean getC(){
Log.i("lz","lz do getC =" + c);
return c;
}
public void printA(){
Log.i("lz","lz do printA a=" + a);
}
public void printAB(int a){
Log.i("lz","lz do printA a=" + a);
}
}


获取Utils类中的所有变量

//get all fields by class
public static StringBuffer getAllFields(){
StringBuffer sb = new StringBuffer();
try {
//第一种
//            Class c = Class.forName("类的目录.Utils");
//第二种
Class c = l.loadClass("类的目录.Utils");
Object o = c.newInstance();
Field d[] = c.getDeclaredFields();
sb.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() + "\n");
for (Field f:d) {
f.getName();
sb.append("\t");//空格
sb.append(Modifier.toString(f.getModifiers())+" ");//获得属性的修饰符,例如public,static等等
sb.append(f.getType().getSimpleName() + " ");//属性的类型的名字
sb.append(f.getName()+";\n");//属性的名字+回车
}
Log.i("lz","lz do info class=" + sb);
return sb;
} catch (ClassNotFoundException e) {
e.printStackTrace();
Log.i("lz","lz do class 11111111111111111");
} catch (InstantiationException e) {
e.printStackTrace();
Log.i("lz","lz do class 22222222222222222");
} catch (IllegalAccessException e) {
Log.i("lz","lz do class 333333333333333333");
e.printStackTrace();
}
return sb;
}


      获取制定名字的变量并且赋值

//set reflect field by give field name
public static String getFieldByName(String name){
Class c = null;
try {
c = l.loadClass("累的目录.Utils");
Object o = c.newInstance();
Field f = c.getDeclaredField(name);
//打破封装
f.setAccessible(true); //使用反射机制可以打破封装性,导致了java对象的属性不安全。
f.set(o,"set do");//设置name的变量的值是set do字符串
return ((Utils)o).getA();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return "";
}


获取所有的方法

public static String getAllMethods(){
Class c = null;
StringBuffer sb = new StringBuffer();
try {
c = l.loadClass("类的目录.Utils");
Method m[] = c.getDeclaredMethods();
for (Method me:m) {
sb.append(Modifier.toString(me.getModifiers()) + " " + me.getName()
+ " " + me.getReturnType() + "\n");
for (Class cl:me.getParameterTypes()) {
sb.append("\t" + cl.getName() + "\n");
}
}
return sb.toString();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return "";
}


    获取指定的方法
public static void doMethodByGiveParams(String methName,Class params[],@android.support.annotation.Nullable Object args[]){
Class c = null;
try {
c = l.loadClass("类的目录.Utils");
Method m = c.getMethod(methName,params);
//出入参数,执行指定的方法,如果有返回值,返回o,方法无参数,args不传 //m.invoke(c)
Object o = m.invoke(c,args);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}


细心的朋友可能已经注意到加载类的两个不同的方法,下面讲述Class.forname 和ClassLoader.loadClass的区别,稍后敬上... ...
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: