黑马程序员_反射

来源:互联网 发布:魔兽for mac 编辑:程序博客网 时间:2024/06/14 17:04

----------- android培训java培训期待与您交流!------------

反射机制:对一个类进行动态的获取并创建对象,并调用该类中的内容。 
获取字节码文件对象的方式。
 
方式一:
使用Object类中的getClass方法。
该方式必须先创建未知类的对象,在调用getClass方法。
 
方式二:
使用静态的class属性就可以获取。
该方式还是需要使用未知的类。
 
方式三:
通过Class类中的静态方法 forName(className)完成;
只要通过类名就可以获取到对应的字节码文件对象。
这种方式的扩展性是最好的。
forName:
1,根据传入的类的名称,自动去classPath路径下去找寻与该名称相同的类文件。
2,通过类加载器将该类进行加载,并在内存中生成该类的字节码文件对象。

反射字段。

public static void getFieldDemo() {String className = "cn.yy.bean.Person";/* * 获取指定类中的指定名称的字段。 * 思路: * 1,通过类名获取字节码文件对象。 * 2,通过字节码文件对象获取其中的成员字段。 *///1,获取字节码文件对象。Class clazz = Class.forName(className);//2,通过Class对象的方法获取字段。//Field field = clazz.getField("age");//该方法只能访问公有的。Field field = clazz.getDeclaredField("age");//可以访问已声明的字段。包括私有。//要想对指定属性进行值的设置。必须要先有指定类的对象。Object obj = clazz.newInstance();//取消权限检查。field.setAccessible(true);//暴力访问。//对字段进行值的设置,需要使用字段对象来完成。field.set(obj, 30);System.out.println(field.get(obj));}


反射构造函数。
public static void getConstructorDemo() {String className = "cn.yy.bean.Person";Class clazz = Class.forName(className);//之前是通过newInstance进行指定的类的实例化。但是该类中如果没有空参数构造函数呢?//或者想通过指定的构造函数进行该类的对象实例化呢?/* * 1,必须先要获取指定的构造函数。 * 2,通过获取到的构造函数对对象进行初始化。 */Person p = new Person("lisi",20);//1,如何获取构造函数呢?通过Class对象。Constructor constructor = clazz.getConstructor(String.class,int.class);//2,如何初始化,构造器最清楚。Object obj = constructor.newInstance("lisi",20);}

反射方法。
public static void getMethodDemo() throws Exception{String className = "cn.yy.bean.Person";Class clazz = Class.forName(className);//获取指定类中的指定方法。Method method = clazz.getMethod("show", null);//可以访问已声明的字段。包括私有。//Method method = clazz.getDeclaredMethod("show4", null);//暴力访问。//method.setAccessible(true);//获取公有,带参数的函数//Method method = clazz.getMethod("show2", String.class,int.class);//获取公有静态的空参数函数。//Method method = clazz.getMethod("show3", null);//method.invoke(null, null);//获取指定类的对象。Object obj = clazz.newInstance();//调用方法对象的invoke方法。method.invoke(obj,null);}


反射应用
public class NoteBookTest {public static void main(String[] args) throws Exception {/* *  * 需求:笔记本电脑运行。 * 增加需求:想使用一个鼠标。 * 可以对鼠标进行描述。 * 并在笔记本中定一个使用鼠标的方法。 * public void useMouse(Mouse m){ *m.open(); *m.close(); *} *虽然这样可以运行,但是日后如果在有其他设备比如摄像头等设备,还是修改笔记本类。 *不利于扩展。 * * 该程序在定义时并未考虑扩展性。 *  *  * 以后出现的功能会有很多。而且未知。 * 为了降低后期设备和笔记本的耦合性。 * 在前期应该先定义规则。笔记本使用这个规则,后期的设备只要符合这个规则笔记本就可以使用。 *  * 定义规则: * 只要是符合usb规范的设备笔记本都可以用。 * 在描述笔记本。 *  *  * 后期,要使用鼠标。 * 该鼠标必须符合usb的规则。 * 描述鼠标实现USB接口,并将鼠标对象作为参数传递给笔记本即可。 *  * 但是对于一个已经可以运行的应用程序,不建议在改动它的源码。 *  * 为了进一步提高扩展性,对于未知子类可以通过反射技术来完成。 * 哪就必须在编写该应用程序时,加入反射机制。 *  *  *  */NoteBook book = new NoteBook();book.run();book.useUSB(null);        //book.useUSB(new MouseByUSB());/* * 后期设备不确定,可以作为参数传递, * 参数如何获取呢? * 在不改动源程序的情况下,可以通过对外提供配置文件的形式。 *  *///定义一个配置文件对象。File configFile = new File("temp\\usb.properties");if(!configFile.exists()){configFile.createNewFile();}//读取配置文件中的信息。Properties prop = new Properties();FileReader fr = new FileReader(configFile);prop.load(fr);for(int x=1; x<=prop.size(); x++){String className = prop.getProperty("usb"+x);//获取指定类的字节码文件对象。Class clazz = Class.forName(className);//创建该类的实例。USB usb = (USB)clazz.newInstance();book.useUSB(usb);}fr.close();}}

0 0
原创粉丝点击