* 反射:
* 什么是反射?* 反射就是将java类中的各种成份映射成相应的java类。
* 如:一个java类用一个Class实例来表示,一个类中各种成份:成员变量、成员方法、构造器、包等信息,分别用
* Field、Method、Constructor、Package中的一个实例来表示,简单说:反射就是可以对类进行解剖。
<span style="font-size:18px;">//Constructor类:代表的是某一个类中的构造方法。
//得到String类中所有构造方法。
Constructor[] constructors=String.class.getConstructors();
for(Constructor constructor:constructors){
System.out.println(constructor);
}
//new String(new StringBuffer("abc"))
//String中有多个构造方法,到底要调用哪一个呢?是用参数列表的类型和个数来确定的。
Constructor constructor=Class.forName("java.lang.String").getConstructor(StringBuffer.class);
//根据面向的对象思想,得到构造器后可以用来创建对象。
//为什么要强转?注意java分为编译阶段和运行阶段。
//调用获得的方法时要用到上面相同类型的实例对象。
String str2=(String)constructor.newInstance(new StringBuffer("abc"));
System.out.println(str2.charAt(1));
//Class的newInstance()方法。
//其实调用的也是Constructor的空参构造 方法,这样做是为了方便书写。
//而且还用到了缓存技术,从某一个角度来看,反射是比较消耗内存的。
String str3=String.class.newInstance();
//Method类:代表的是某一个类中的成员方法。
Method[] methods=String.class.getMethods();//返回公共的方法,包含继承的方法。
// Method[] methods=String.class.getDeclaredMethods();//返回全部方法,不包含继承的方法。
for(Method method :methods){
System.out.println(method);
}
String s="abc";
//s.charAt(1);
Method charAtMethod=String.class.getMethod("charAt", int.class);
//调用获得的方法时需要用到上面相同类型的实例对象。
//注意:jdk1.4的语法:invoke(Object[])
// jdk1.5的语法:invoke(Object...args)
Object retVal=charAtMethod.invoke(s, 1);
System.out.println(retVal);
//Field类:代表的是某一个类中的成员变量。
// Field[] fields=ReflectPoint.class.getFields();
//ReflectPoint是一个用于辅助类。下最后面。
ReflectPoint pt1= new ReflectPoint(3,4);
Field fieldY=ReflectPoint.class.getField("y");//得到公有的
//fieldY的值是多少?是3?
//fieldY是类上的变量,不是对象上的变量,
System.out.println(fieldY.get(pt1));//3
Field fieldX=pt1.getClass().getDeclaredField("x");//私有也可见。
//因为是私有的 不可访问。也就是说,可以看到,但是不能用。我一定要用呢?
fieldX.setAccessible(true);//取消权限检查,暴力反射。
//思考:既然程序中的变量已经定义为private,就是不想让外界访问了,干嘛还整个暴力反射呢?
//private是给javac编译器看的,希望在写程序的时候,在源代码中不要访问,是帮程序员
//实现高内聚、低耦合的一种策略,程序员不领情,非要访问,javac编译器也不会拦着。
System.out.println(fieldX.get(pt1));
//======*******======
/*
* 较为复杂的综合应用。
* 将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的“b"改为"a";
*/
Field[] fields=pt1.getClass().getFields();
for(Field field : fields)
{
// if(field.getType().equals(String.class)){
// 因为字节码只有一份,用==语意更加精准。
if(field.getType() == String.class){
String oldValue=(String)field.get(pt1);
String newValue=oldValue.replace('b', 'a');
field.set(pt1, newValue);
}
}
System.out.println(pt1);</span>
辅助类:
<span style="font-size:18px;">public class ReflectPoint {
private int x;
public int y;
public String s1="beat it";
public String s2="basketball";
public String s3="hbb";
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ReflectPoint other = (ReflectPoint) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
@Override
public String toString() {
return s1+":"+s2+":"+s3;
}
}</span>