黑马程序员——反射

来源:互联网 发布:kz解压软件 编辑:程序博客网 时间:2024/06/05 00:51

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

一、反射机制简介

 JAVA反射弧机制是在运行状态中对于任意一个类,都能知道这个类的所有属性和方法
  对于任意一个对象,都能够调用它的任意一个方法和属性
  这种动态获取信息以及动态调用对象的方法功能称为java语言的反射机制
 
   动态获取类中的信息,就是jva反射
   可以理解为对类的解剖
  
   要想要对字节码文件进行解剖,必须要有字节码文件对象
   如何获取字节码文件对象呢?
 

class Class该类提供获取字节码文件中的内容,比如:名称、字段、构造函数、一般函数。

该类就可以获取字节码文件中的所有内容,反射就是依靠该类来完成的。

想要对一个类文件进行解剖,只要获取该类的字节码文件对象即可


获取字节码文件对象的方法演示:

import cn.itcast.bean.Person;public class ReflectDemo {public static void main(String[] args) throws ClassNotFoundException {getClassObject_3();}/* * 方式三: * 只要用过给定的类的字符串名称就可以获取该类,更为扩展 * 可以用Class类中方法完成 * 该方法就是forName * 这种方式一要有名称即可,更为方便,扩展性更强*/public static void getClassObject_3() throws ClassNotFoundException {String className="cn.itcast.bean.Person";Class clazz=Class.forName(className);System.out.println(clazz);}/* * 方式二: * 2,任何数据类型都具有一个静态的属性。class来获取其对应的Class对象 * 相对简单,但是还是哟明确到类中的静态成员 * 还是不够扩展*/public static void getClassObject_2() {Class clazz=Person.class;Class clazz1=Person.class;System.out.println(clazz==clazz1);}/* * 获取字节码对象的方式 * 1,Object类中的getclass()方法 * 想要用这种方式,必须要明确具体的类,并创建对象 * 麻烦*/public static void getClassObject_1() {Person p=new Person();Class clazz=p.getClass();Person p1=new Person();Class clazz1=p1.getClass();System.out.println(clazz==clazz1);}}

二、利用反射创建对象

import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class ReafectDemo2 {public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {createNewObject_2();}public static void createNewObject_2() throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {/* * 当获取指定名称对应的类中所体现的对象时, * 而该对象初始化不使用空参数构造该怎么办呢 * 既然是通过指定的构造函数,进行对象的初始化 * 所以应该先获取到该构造函数。通过字节码文件对象即可完成 * 该方法是:getConstructor(paramterTypes);*/String name="cn.itcast.bean.Person";//找寻该名称类文件,并加载进内存,并产生Class对象Class clazz=Class.forName(name);//获取到了指定的构造函数对象Constructor constructor=clazz.getConstructor(String.class,int.class);//通过该构造器对象的newInstance方法进行对象的初始化Object obj=constructor.newInstance("小明",38);}public static void createNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException{//早期:new的时候,先根据被new的类的名称找寻该类的字节码文件,并加载进内存,//并创建该字节码文件对象,并接着创建该字节码文件对应的Person对象//cn.itcast.bean.Person p=new cn.itcast.bean.Person();//现在:String name="cn.itcast.bean.Person";//找寻该名称类文件,并加载进内存,并产生Class对象Class clazz=Class.forName(name);//如何产生该类的对象呢?Object obj=clazz.newInstance();}}

三、获取字节码对象中的字段

import java.lang.reflect.Field;public class ReflectDemo3 {public static void main(String[] args) throws Exception {getFieldDemo();}/* * 获取字节码文件中的字段*/public static void getFieldDemo() throws Exception {Class clazz=Class.forName("cn.itcast.bean.Person");Field field=clazz.getDeclaredField("age");//只获取本类,但包含私有//对私有字段的访问取消权限检查,暴力访问field.setAccessible(true);Object obj=clazz.newInstance();field.set(obj, 89);Object o=field.get(obj);System.out.println(o);}}

四、获取字节码文件中的方法

import java.lang.reflect.Constructor;import java.lang.reflect.Method;public class ReflectDemo4 {public static void main(String[] args) throws Exception {getMethodDemo_3();}public static void getMethodDemo_3() throws Exception {Class clazz=Class.forName("cn.itcast.bean.Person");Method method=clazz.getMethod("paramMethod", String.class,int.class);//Constructor constructor=clazz.getConstructor(String.class ,int.class);Object obj=clazz.newInstance();method.invoke(obj, "小明",37);}public static void getMethodDemo_2() throws Exception {Class clazz=Class.forName("cn.itcast.bean.Person");Method method=clazz.getMethod("show", null);//获取空参数一般方法Constructor constructor=clazz.getConstructor(String.class,int.class);Object obj=constructor.newInstance("小明",37);method.invoke(obj, null);}/* * 获取指定Class中的公共函数*/public static void getMethodDemo() throws Exception {Class clazz=Class.forName("cn.itcast.bean.Person");Method[]methods=clazz.getMethods();//获取的都是公有的方法methods=clazz.getDeclaredMethods();for(Method method:methods){System.out.println(method);}}}


模拟一个电脑运行,通过反射机制为电脑添加新的功能:

/* * 电脑运行。*/import java.io.File;import java.io.FileInputStream;import java.util.Properties;public class ReflectTest {public static void main(String[] args) throws Exception {Mainboard mb = new Mainboard();mb.run();// 每次添加一个设备都需要修改代码传递一个新创建的对象//mb.use(new SoundCard());// 能不能不修改代码就可以完成这个动作// 不用new来完成,而是直接获取其class文件,在内部完成创建对象的动作File configFile = new File("pci.properties");Properties prop = new Properties();FileInputStream fis = new FileInputStream(configFile);prop.load(fis);for (int x = 0; x < prop.size(); x++) {String pciName = prop.getProperty("pci" + (x + 1));Class clazz=Class.forName(pciName);//用Class去加载这个pci子类PCI p=(PCI)clazz.newInstance();mb.usePCI(p);}fis.close();}}

public class Mainboard {public void run(){System.out.println("main board run");}public void usePCI(PCI p){if(p!=null){p.open();p.close();}}}


public class SoundCard implements PCI{public void open(){System.out.println("sound open");}public void close(){System.out.println("sound close");}}


------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

0 0