反射机制笔记

反射机制:

 反射 Reflectoin
反射机制是Java的一个非常重要的机制。一
些著名的应用框架都使用了此机制。
例如,
struts, spring, hibernate
android app的界面设计器 …
在设计应用框架时一般都要使用反射,它是
Java的一个非常优越的特性。
 
例如,
Class cls = Student.class;
System.out.println("Name: " + cls.getName());
其中,cls这个对象就是这个Class的描述。
再例如,
Student obj = new Student(); 
Class cls = obj.getClass();
其中,obj是一个对象,obj.getClass()则是获取它的Class
描述。
 
Class的作用
  用于判断一个运行时对象的类型
public static void test1(Object obj)
{
Class cls = Student.class;
if(cls.isInstance(obj))
{
}
}
其中,cls.Instance(obj)意思是判断obj是否为my.Student
的一个实例
 
另一种写法,也可以判断一个运行时对象的类型
public static void test2(Object obj)
{
String clsName = obj.getClass().getName();
if(clsName.equals("my.Student"))
{
}
}
其中,obj.getClass()可以得到对象obj的具体类型
 
应用展示
让一个对Student对象可以与String和Integer进行比较。。。
public boolean equals(Object obj)
{
// 与一个String对象比较
if(String.class.isInstance(obj))
{
String other = (String)obj;
return other.equals(this.name);
}
// 与一个Integer对象比较
if(Integer.class.isInstance(obj))
{
Integer other = (Integer)obj;
return this.id == other;
}
return false;
}
 
 
Reflection
给定一个*.class文件中,我们可以得到以下信息:
 类名 (含package路径)
 函数 (名称,参数类型,返回值)
 域 (名称,类型)
 实现的接口 (interfaces)
… …
使用java.lang.reflect.*下的类来实现
动态加载一个*.class文件到内存:
// 加载my/Student.class
Class cls = Class.forName("my.Student");
// 获取函数列表
Method[] methods = cls.getMethods();
// 获取成员变量列表
Field[] fields = cls.getFields();
也就是说,虽然我们不知道Student类的代码,但是这个
class文件本身可以反映(reflect)出这些信息。。。
 结论:通过Reflection机制,我们可以直接
从class文件反推出它有哪个成员变量、有哪
些函数
 
例1 遍历Method 已经函数名,找到对象的 Method
Class cls = …
String methodName = "setId";
// 获取所有Method列表,顺序比对
Method[] methods = cls.getMethods();
for(Method m : methods)
{
if(m.getName().equals(methodName))
{
break;
}
}
 
例2 查找Method 
已经函数名,参数列表,寻找Method
Class cls = …
String methodName = "setId";
Class[] parameterTypes = { int.class };
Method m = cls.getMethod(methodName, 
 parameterTypes);
 
 
例3 Reflection的运用
// 创建一个实例, 要求有一个不带参数的构造函数
Object obj = cls.newInstance();
// 找到method
Class[] parameterTypes = { int.class };
Method m1 = cls.getMethod("setId", 
 parameterTypes);
// 调用method
Object[] paramters = { 123 };
m1.invoke(obj, paramters);
 
更多细节 Class Loader
Class.forName(…) 可以加载一个class文件。。
(1)由谁负责加载?
由Class Loader负责加载,具体地讲,JVM提供了一
个内置的 bootstrap class loader。
(2)从哪里加载?
从classpath下寻找class,以及该class里面import
的class
 
 
 
 
posted @ 2019-04-18 15:07  一杯香米酒  阅读(179)  评论(0编辑  收藏  举报