------- android培训、java培训、期待与您交流! ----------
反射
反射就是把java类中的各种成分映射成相应的java类。
例如:一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,修饰符、包等信息用一个个的java类来表示。
//编译器只看变量的定义不看代码的执行
l Constructor 类代表某个类中的一个构造方法
1)得到某个类所有的构造方法:
例子:
Constructor[] constructors =
Class.forName(“java.lang.String”).getConstructor();
//class—>constructor-->new object
2)得到某一个构造方法:
例子:
Constructor constructor =
Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
3)创建实例对象
通常方式:String str = new String(new StringBuffer(“abcd”));
反射方式:String str =
(String)constructor. newInstance(new StringBuffer("abc"));
//调用获得的方法时要用到上面相同类型的实例对象
4)Class.newInstance()方法
例子:String obj = (String) Class.forName(“java.lang.String”).newInstance();
该方法内部先得到默认的构造方法,然后用构造方法创建实例对象。
用缓存机制保存默认构造方法的对象。
new String(new StringBuffer("abc"))
Constructor constructor = String.class.getConstructor(StringBuffer.class);//表示选择了哪个构造方法(类型)
String str2=(String) constructor.newInstance(new StringBuffer("abc"));//表示用这个构造方法时,传递的StringBuffer对象(同样类型的对象)
System.out.println(str2.charAt(1));
l Field类代表某个类中的一个成员变量
ReflectPoint pt1 = newReflectPoint(3, 5);
Field fieldY = pt1.getClass().getField("y");
//fieldY代表类字节码中的变量,不是对象本身的变量,而是类上,要用它去取某个对象的值
System.out.println(fieldY.get(pt1));
Field fieldX = pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);//暴力反射(变量为私有)看见了取不到用暴力反射
System.out.println(fieldX.get(pt1));
实例:
public class ReflectPoint {
privateint x;
publicint y;
public String str1 ="ball";
publicString str2 = "basketball";
publicString str3 = "itcast";
//自动生成构造函数
publicReflectPoint(intx, inty) {
super();
this.x= x;
this.y= y;
}
}
private static void changeStringValue(Object obj) throwsIllegalArgumentException
Field[] fields = obj.getClass().getFields();
for(Field field:fields){
//if(field.getType().euqals(String.class))
//因为是同一份字节码
if(field.getType()==String.class) {
String oldValue = (String)field.get(obj);
String newValue = oldValue.replace('b','a');
field.set(obj, newValue);
}
}
}
l Method类代表某个类中的一个成员方法
1)得到类中的某一个方法:
例子:Method charAt =
Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);
2)调用方法
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
如果传递给method对象的invoke()方法的第一个参数为null,则该method对象对应的是一个静态方法!
3)Jdk1.4与jdk1.5中invoke方法的区别(可变参数)
//拿出字节码的方法再作用于某个对象
Method methodCharAt = String.class.getMethod("charAt",int.class);
System.out.println(methodCharAt.invoke(str1, 1));
//jdk1.4的调用方法
System.out.println(methodCharAt.invoke(str1,newObject[]{2}));
//1.5 可变参数
methodCharAt.invoke(Object obj,O bject[] args);
对接收数组参数的成员方法进行反射
u 用反射方式执行某个类中的main方法
class TestArguments {
publicstatic voidmain(String[] args) {
for(String arg :args){
System.out.println(arg);
}
}
//调用main方法
//TestArguments.main(new String[]{"123","345","sss"});
//用反射去调用
String startingStringClassName = args[0];
Method mainMethod = Class.forName(startingStringClassName).getMethod("main", String[].class);
mainMethod.invoke(null, new Object[]{new String[]{"ss","123"}});
mainMethod.invoke(null,(Object)newString[]{"ss","123"});
l 数组的反射
元素类型相同与维数相同 属于同一类型,具有相同的Class实例对象
注意:基本类型的一维数组可以被当作Object类型使用,不能当作能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以做Object[]类型使用。
Arrays.aslist()方法处理int和String[]时的差异--
不能得到整个数组的类型 可以得到某个值的类型
例子:a[0].getClass().getName();
//数组
int[] a1 =new int[3];
int[] a2 =new int[4];
int[][] a3 =new int[2][3];
String[] a4 =new String[]{"ad","bd","cd"};
System.out.println(a1.getClass()==a2.getClass());
//System.out.println(a1.getClass()==a4.getClass());
//System.out.println(a1.getClass()==a3.getClass());
System.out.println(a1.getClass().getName());
System.out.println(a1.getClass().getSuperclass().getName());
System.out.println(a4.getClass().getSuperclass().getName());
ObjectaObj1 = a1;
ObjectaObj2 = a4;
//Object[] aObj3 = a1; int不是object
Object[]aObj4 = a3;
Object[]aObj5 = a4;
System.out.println(a1);
System.out.println(a4);
System.out.println(Arrays.asList(a1));//一个参数
System.out.println(Arrays.asList(a4));
printlnObject(a4);
printlnObject(123);
privatestatic voidprintlnObject(Object obj) {
Class clazz = obj.getClass();
if(clazz.isArray()) {
intlen = Array.getLength(obj);
for(inti = 0; i < len; i++) {
System.out.println(Array.get(obj, i));
}
}else {
System.out.println(obj);
}
l ArrayList_HashSet的比较及Hashcode分析
Arraylist 是否相同都存入引用
Hashset 如果集合中有则不存入。
Hashcode 的作用:每个集合分区域哈希值对应区域(提高查找效率)提高对集合操作的效率 (内存泄漏) (内存一直被占用)
l 反射的作用--->实现框架功能
框架:别人调用你的类
框架要解决的核心问题:利用反射
InputStream ips= newFileInputStream("config.properties");
Properties ps =new Properties();
ps.load(ips);
ips.close();
String className = ps.getProperty("className");
Collection collections = (Collection)Class.forName(className).newInstance();
GetRealPath
得到资源文件的方法??
u 内省 introSpector --->javaBean-->特殊的java类
javaBean 是一种特殊的java类,主要用于传递信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
JavaBean的属性根据方法名得出
Age -->如果第二个字母是小写,则第一个字母变成小的—>age
gettime-->time
getTime-->time
getCPU--->CPU
例:public class IntroSpectorTest {
publicstatic voidmain(String[] args) throwsException{
//TODO Auto-generated method stub
ReflectPoint pt1 =new ReflectPoint(3,4);
String propertyName ="x";
//x-->X-->getX-->MethodGetX
PropertyDescriptor pd =new PropertyDescriptor(propertyName, pt1.getClass());
Method methodGetX =pd.getReadMethod();
Object retVal =methodGetX.invoke(pt1, args);
System.out.println(retVal);
Object retVal1=getProperty(pt1, propertyName);
System.out.println(retVal1);
Method methodSetX = pd.getWriteMethod();
methodSetX.invoke(pt1, 7);
System.out.println(pt1.getX());
Object value = 9;
setProperty(pt1, propertyName, value);
System.out.println(pt1.getX());
}
privatestatic voidsetProperty(Object pt1,String propertyName,Object value)throws IntrospectionException, IllegalAccessException, IllegalArgumentException
PropertyDescriptor pd2 =new PropertyDescriptor(propertyName, pt1.getClass());
Method methodSetX = pd2.getWriteMethod();
methodSetX.invoke(pt1, value);
}
privatestatic Object getProperty(Object pt1,String propertyName1) throwsException{
BeanInfo beanInfo =Introspector.getBeanInfo(pt1.getClass());//javaBean来看这个类
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();//得到属性描述
Object retValu =null;
for(PropertyDescriptor pd:pds){
if(pd.getName().equals(propertyName1)){
Method methodGet =pd.getReadMethod();
retValu = methodGet.invoke(pt1);
break;
}
}
returnretValu;
}
}
------- Windows Phone 7手机开发 、 .Net培训 、期待与您交流! -------