---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------
反射
一:得到字节码有2种情形
1.类已经加载进内存,要得到它只要找到它将其放回即可
2.在java虚拟机中还没有字节码,就要用类加载器去加载,加载后将字节码缓存起来,同时,用forName()放回加载的字节码.
二:得到字节码的实例对象有3种方式(class类型)
1.类名.class;
2.对象.getclass();
3.Class.forName();有9个预定义的Class对象,即8个基本数据类型+void类型
有几个重要的方法:
isPrimitive();判断是否是原始类型
isArray();判断是否是数组
Type可以将包装类型转成基本类型,如:int.class = Integet.Type;
三.对构造函数的反射
public class ReflectDemo {
/**
* @param args
* @throws Exception
* @throws NoSuchFieldException
* @throws Exception
* @throws NoSuchMethodException
* @throws Exception
*/
public static void main(String[] args) throws NoSuchFieldException, Exception {
/*String str = "asc";
Class clazz1 = str.getClass();
Class clazz2 = String.class;
Class clazz3 = null;
try {
clazz3 = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(clazz1==clazz2);
System.out.println(clazz2==clazz3);*/
//new String(new StringBuffer("qwe"));
/*Constructor constructor = String.class.getConstructor(StringBuffer.class);
String str =(String)constructor.newInstance(new StringBuffer("qwe"));
System.out.println(str.charAt(3));*/
ReflectPoint reflectpoint = new ReflectPoint(3, 5);
Class ref = reflectpoint.getClass();
Field filedy = ref.getField("y");
Field filedx = ref.getDeclaredField("x"); //私有的,用获取所有字段方法
filedx.setAccessible(true); //设置字段可见,实现暴力反射
System.out.println(filedy.get(reflectpoint));
System.out.println(filedx.get(reflectpoint));
}
}
四.对成员字段的反射
public class ReflectDemo1 {
/**
* @param args
* @throws Exception
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws IllegalArgumentException, Exception {
ReflectDemo reflectDemo = new ReflectDemo();
Class clazz = Class.forName("cn.itcast.ReflectPoint");
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.getType()==String.class) { //判断是否是String类型,可能是同一个字节码,因此用等号判断
String oldStr = (String)field.get(reflectDemo);
String newStr = oldStr.replace("a", "b");
field.set(reflectDemo, newStr);
}
}
}
}
五.对方法的反射
public class MethodReflect {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("cn.itcast.reflectpoint");
Method method = clazz.getMethod("getX");
method.invoke(ReflectPoint.class);
System.out.println(method);
}
}
六:数组与Object的关系及反射类型
1.数组具有相同的类型(如int)并且有相同的维度时(同是一维或同是二维),他们的字节码相同
2.基本类型的一维数组不能转换成Object的数组,例:
import java.util.Arrays;
public class ArrayReflect {
/**
* @param args
*/
public static void main(String[] args) {
/*int[] arr1 = new int[2];
int[] arr2 = new int[3];
int[][]arr3 = new int[2][3];
String [] arr4 = new String[4];
System.out.println(arr1.getClass()==arr2.getClass());
//System.out.println(arr1.getClass()==arr4.getClass());
//System.out.println(arr1.getClass()==arr3.getClass());
System.out.println(arr1.getClass().getSuperclass().getName());
Object object1 = arr1;
Object object2 = arr2;
Object[] objects3 = arr3;
Object[] objects4 = arr4;*/
//Object[] objects5 = arr1;
//Object[] objects6 = arr2;
int[] ar1 = new int[]{3,4,7,2};
String[] ar2 = new String[]{"qwe","ff","ww"};
System.out.println(Arrays.asList(ar1));
System.out.println(Arrays.asList(ar2));
}
}
七:内存泄露问题
当一个对象被存储进HashSet集合后,就不能修改这个对象中那些参与计算的哈希值字段,否则被修改后的哈希值与最初被存进HashSet集合中的哈希值就不一样了,在这种情况下,无法对对象的当前引用进行删除,造成内存泄露.
八:反射的作用:实现框架功能
框架要解决的核心问题:
在写程序的时候无法知道要被调用的类名,所以在写程序时无法直接new某个类的实例对象,因此要用反射的方式来做,例:
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Properties;
public class FrameReflectDemo {
/**
* @param args
* @throws Exception
* 用类加载器加载配置文件
*/
public static void main(String[] args) throws Exception {
//InputStream in = new FileInputStream("config.propertise");
InputStream in = FrameReflectDemo.class.getResourceAsStream("config.propertise");
Properties propes = new Properties();
propes.load(in);
in.close();
String className = propes.getProperty("className");
Collection collection =(Collection)Class.forName(className).newInstance();
collection.add(new ReflectPoint(3, 5));
collection.add(new ReflectPoint(4, 3));
collection.add(new ReflectPoint(2, 8));
System.out.println(collection.size());
}
}
八:其他
反射:就是把java类中的各种成分映射成相应的java类,编译器只看变量的的定义,不看代码的执行.
反射会导致程序性能的下降,因为里面缓存了构造方法.
为什么要用反射的方式调用函数?因为在执行前比昂不知到要执行那个类.
成员方法的反射:当对象设置为null时,说明它调用的是一个静态方法
取得私有的构造函数,变量或方法时,需要用到暴力反射
---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IO开发S</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------