------- android培训、java培训、期待与您交流! ----------
反射机制
Java程序中的各个Java类属于同一类事物,描述这类事物的Java类名就是Class
Class描述了哪些方面的信息呢?
类的名字 类的访问属性 类所属于的包名 字段名称的列表 方法名称的列表等。
JAVA反射机制是在运行状态中,对于任意一个类(class文件)。都能够知道这个类的所有属性和方法。
对于任意一个对象,都能够调用它的任意一个方法和属性。
这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
动态获取类中信息,就是Java反射。
以理解为对类的解剖。
使用反射技术,应该导入的包是java.reflect.*;
反射会导致程序的性能严重下降
反射概述图例:
获取Class对象的三种方式:
/*方式一:
* 获取字节码对象的方式:
* 1、Object类中的getClass方法。
* 想要用这种方式,必须要明确具体的类,并创建对象。
* */
public staticvoidgetClassObject_1()
{
Personp = newPerson();
Classclazz = p.getClass();
Personp1 = newPerson();
Classclazz1 = p1.getClass();
System.out.println(clazz==clazz1);
}
/*方式二:
* 2、任何数据类型都具备一个静态的属性.class来获取其对应的class对象。
* 相对简单,但是还是要需要明确用到类中的静态成员。
* 还是不够扩展。
* */
public staticvoidgetClassObject_2()
{
Classclazz = Person.class;
Classclazz1 = Person.class;
System.out.println(clazz==clazz1);
}
/*方式三:
* 重点掌握。
* 只要通过给定的类的字符串名称就可以获取该类,更为扩展。
* 可以用Class类中的方法完成。
* 该方法就是forName.
* 这种方式只要有名称即可,更为方便,扩展性更强。
* */
public staticvoidgetClassObject_3() throws ClassNotFoundException
{
Stringclassname = "cn.itcast.bean.Person";
Classclazz = Class.forName(classname);
System.out.println(clazz);
}
图例:
Class.forName()的作用?就是返回字节码
返回的方式有两种:
1,这份字节码曾经被加载过,已经待在java虚拟机中了,就可以直接返回了
2,java虚拟机中还没有这份字节码,则用类加载器去加载,把加载进来的字节码,缓存到虚拟机中,以后要得到这个字节码就不用在加载了。
Class中的构造函数
public staticvoidcreateNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
Stringname = "cn.itcast.bean.Person";
//找寻该名称类文件,并加载进内存,并产生Class对象。
Classclazz = Class.forName(name);
//如何产生该类的对象呢?
Objectobj = clazz.newInstance();
}
public static void createNewObject_1() throws ClassNotFoundException,SecurityException, NoSuchMethodException, IllegalArgumentException,InstantiationException, IllegalAccessException, InvocationTargetException
{
/*当获取指定名称对应类中所体现的对象时,
* 而该对象初始化不使用空参数构造该怎么办呢?
* 既然是通过指定的构造函数进行对象的初始化。
* 所以应该先获取到该构造函数。通过字节码文件对象完成即可。
* 该方法是:getConstructor(paramterType);
* */
Stringname = "cn.itcast.bean.Person";
//找寻该名称类文件,并加载进内存,并产生Class对象。
Classclazz = Class.forName(name);
//获取到了指定的构造函数对象。
Constructorconstructor = clazz.getConstructor(String.class,int.class);
//通过该构造器对象的newInstance方法进行对象的初始化。
Objectobj = constructor.newInstance("小二",23);
}
Class中的字段
/*获取字节码文件中的字段。
*
* */
public static void getFieldDemo() throws SecurityException,NoSuchFieldException, ClassNotFoundException, InstantiationException,IllegalAccessException
{
Classclazz = Class.forName("cn.itcast.bean.Person");
java.lang.reflect.Fieldfield = clazz.getDeclaredField("age");
//System.out.println(field);
//对私有字段的访问取消权限检查。暴力访问。
field.setAccessible(true);
Objectobj = null;
try {
obj= clazz.newInstance();
field.set(obj,89);
}catch(Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Objecto = null;
try {
o= field.get(obj);
}catch(IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(o);
}
/*获取指定Class中的所有公共函数。
*
* */
public static void getMethodDemo() throws Exception
{
Classclazz = Class.forName("cn.itcast.bean.Person");
Method[]methods = clazz.getMethods();//获取的都是公有的方法。
methods= clazz.getDeclaredMethods();//获取本类中所有方法,包含私有。
for(Method method :methods)
{
System.out.println(method);
}
}
public static void getMethodDemo_1() throws Exception
{
Classclazz = Class.forName("cn.itcast.bean.Person");
Methodmethods = clazz.getMethod("show", null);//获取空参数的一般方法。
//Object obj = clazz.newInstance();
Constructorconstructor = clazz.getConstructor(String.class,int.class);
Objectobj = constructor.newInstance("小明",44);
methods.invoke(obj,null);
}
//获取有参数的方法。
public static void getMethodDemo_2() throws Exception
{
Classclazz = Class.forName("cn.itcast.bean.Person");
Methodmethods = clazz.getMethod("paramMethod", String.class,int.class);
Objectobj = clazz.newInstance();
methods.invoke(obj,"小王",55);
}
反射练习:
public classReflcetTest {
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Mainboardmb = newMainboard();
mb.run();
//不用new完成,而是只获取Class文件,在内部实现创建对象的动作。
FileconfigFile = newFile("pci.properties");
Propertiespro = newProperties();
FileInputStreamfis = newFileInputStream(configFile);
pro.load(fis);
for(intx=0;x<pro.size();x++)
{
StringpciName = pro.getProperty("pci"+(x+1));
Classclazz = Class.forName(pciName);//用Class类去加载这个PCI子类。
PCIp = (PCI)clazz.newInstance();
mb.uesPCI(p);
}
fis.close();
}
}