------- android培训、java培训、期待与您交流! ----------
一.相关知识
定义:Java类中的各种成分映射成相应的Java类。
1.起源---反射的基石:Class类
java类也是一种对象,也需要一个更高级的概念将其共性归纳抽取出来,这个更高的概念抽象就是Class类。Class类描述的对象就是java类中的字段,方法,构造器等。
2.作用:在框架开发中需要用到反射技术,因为在开发框架时并不知道后续的使用者要定义什么类。反射的好处:增强了程序的扩展性。
2.如何得到Class类
类名.Class 如:Person.Class
对象.getClass() 如:new Person.getClass()
Class.forName(类名) 如:Class.forName(“java.Util.Date”)
实际开发中主要用第三种,因为在写源程序的时候还不知道类的名字。
3.九个Class预定义的对象
-八个基本数据类型以及void
-可以通过Class对象.isPrimitiver来判断该Class对象是否为这九个预定义对象
-数组的Class判定,Class.isArray()
需要数据类型与维数相等才内判定两数组的Class相同
4.反射的要点:
a) 要点Field, Method, Constructor, Package
b) 一个类的每个成员都能通过相应反射API的一个实例对象来表示,通过对这些实例对象的操作来达到反射的效果。
二.反射的具体操作
1.Constructor获得构造器对象
对于一个类中的多个构造器,可以采用其参数个数与参数类型来区分。
构造器的使用实例
public static void main(String[] args) throws Exception {
//1.通过Constructor的newInstance 新建对象
Constructor [] cst=Class.forName("java.lang.String").getConstructors();//得到所有的构造方法
Constructor<String> ct=(Constructor<String>) Class.forName("java.lang.String").getConstructor(StringBuilder.class);//得到参数为StringBuilder的构造方法
String s=(String) ct.newInstance(new StringBuilder("asdf"));//通过newInstance new了一个对象,但这要强制类型转换
System.out.println(s);
//2.通过Class的newInstance新建对象,不带参数的构造
String s1=(String)Class.forName("java.lang.String").newInstance();
}
}
2.Field获得字段
这里要注意字段一般为对象私有(对象的封装嘛),在取出的时候要用getDeclaredField(),使用时还要加上setAccessible(true);
package com.cn.test;
import java.lang.reflect.*;
class Pointer{
public int x;
private int y;
public String str1="annanan";
public String str2="bannana";
public Pointer(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public String toString() {
return "Pointer [str1=" + str1 + ", str2=" + str2 + "]";
}
}
public class FieldDemo {
public static void main(String[] args) throws Exception {
Pointer p=new Pointer(1,2);
Field fx=p.getClass().getField("x");//拿到类中字段x
//用普通getField()非公有的y字段不可见,会报NoSuchField异常,这里用getDeclaredField
Field fy=Pointer.class.getDeclaredField("y");
System.out.println(fx.get(p));
fy.setAccessible(true);//设置字段的可访问权限
System.out.println(fy.get(p));
//
chageStringValue(p);
System.out.println(p.toString());
}
/**
* 将一个类中的String字段中的a转成b
* @throws Exception
*/
static void chageStringValue(Object obj) throws Exception{
Field [] fields=obj.getClass().getFields();
for (Field field : fields) {
if(field.getType()==String.class){
String oldValue=(String)field.get(obj);
String newValue=oldValue.replace('a','b');
field.set(obj, newValue);
}
}
}
}
3.Method类,方法的反射
使用ivoke()这个方法来执行
package com.cn.test;
import java.lang.reflect.*;
public class MethodDemo {
public static void main(String[] args) throws Exception{
Method mt=String.class.getMethod("charAt", int.class);//通过Class拿到方法
System.out.println(mt.invoke("asdf", 3));//反射运行方法
}
}