(104)反射:获取Class的对象、构造函数、字段、方法。反射实例练习
来源:互联网 发布:access sql limit 编辑:程序博客网 时间:2024/05/19 14:15
反射机制:动态获取类中的信息。可以理解为对类的解剖
在一个已经做好的应用程序中,没有源码,只有对外提供的接口,所以不能创建新的对象。
在反射机制中,只要实现接口,然后在配置文件中写注明该类,在应用程序中就能自动加载
一、获取Class对象的方式:
方式1,Object类中的getClass()方法,想要用这种方式,必须要明确具体的类,并创建对象
car c=new car(); Class clazz=c.getClass(); car c1=new car(); Class clazz=c1.getClass(); Class clazz1=c1.getClass();//返回运行时类 System.out.println(clazz1==clazz);//true
方式2,任何数据类型都具有一个静态的属性:.class来获取其对应的Class对象(相对简单,但是还要明确类中用到的静态成员,不够扩展)
Class clazz=car.class; Class clazz1=car.class; System.out.println(clazz1==clazz);//true
方式3,只要通过给定的类的字符串名称就可以获取该类,扩展性强
可以用Class类中方法来完成:forName,只要指定名称即可
String className="com.Car.car";//必须指定包名的类, Class clazz=Class.forName(className);//该方法抛异常 System.out.println(clazz);
二、获取Class中的构造函数
//早期:new 时,先根据被new的类的名称找到该类的字节码文件,加载进内存并创建该字节码文件对象,然后创建该字节码文件对应的person对象 //com.Car.person p=new com.Car.person(); //现在: String className="com.Car.person"; Class clazz=Class.forName(className);//获取到了class字节码文件对象 //Object obj=clazz.newInstance(); //创建该字节码文件对应的person对象,获取的是无参的构造函数对应的对象 Constructor constructor=clazz.getConstructor(String.class,int.class);//创建该字节码对应的person对象,获取含参的构造函数对象 //通过该构造器的newInstance创建person对象含参的实例 constructor.newInstance("张三",15);
三、获取Class中的字段
//创建对象 Class clazz=Class.forName("com.Car.person"); Object obj=clazz.newInstance(); //获取公共字段 Field f=clazz.getField("sex");//只能获取公共字段 System.out.println(f);//public java.lang.String com.Car.person.sex //获取指定字段属性的值 Object objField=f.get(obj); System.out.println(objField); //获取任Object何权限的字段 Field f1=clazz.getDeclaredField("age"); System.out.println(f1);//private int com.Car.person.age //获取特定对象的该字段值 //Object objField1=f1.get(obj);//java.lang.IllegalAccessException私有字段,不能访问java.lang.IllegalAccessException //若非要访问,则可以通过父类继承过来的方法,对私有字段的访问权限取消检查(暴力访问) f1.setAccessible(true); Object objField1=f1.get(obj); System.out.println(objField); //设置字段的值 f1.set(obj, 60);//在指定对象上字段设置值 System.out.println(f1.get(obj));
四、获取Class中的方法
Class clazz=Class.forName("com.Car.person"); //Object obj=clazz.newInstance(); //获取包括父类的所有公共方法 Method [] method=clazz.getMethods(); for(Method m:method) { //System.out.println(m); } //获取本类中写的所有方法,不包含父类继承 Method[] method1=clazz.getDeclaredMethods(); for(Method m:method1) { //System.out.println(m); } //获取一个方法(无参) Method method2=clazz.getMethod("run", null); //System.out.println(method2);//public void com.Car.person.run() //想要让run中的值是某个对象的值 Constructor construct=clazz.getConstructor(String.class,int.class); Object obj=construct.newInstance("小强",20); //想要运行这个方法 method2.invoke(obj, null);//没返回值,直接在方法中输出了 //获取一个方法含参 Method method3=clazz.getMethod("show", int.class,int.class); method3.invoke(obj,80,63);
五、反射练习
在主板中可以有声卡等插件,在以前的学习中的做法是如下这样的:
package com.Car1;public class mainBoard { public void run() { System.out.println("main.......run"); } public void useSoundCard(soundCard sc) { sc.open(); sc.close(); } public static void main(String[] args) { mainBoard mb=new mainBoard(); mb.useSoundCard(new soundCard()); //这样做法的坏处就是要加网卡的话,还要修改网卡的代码,扩展性差 }}package com.Car1;public class soundCard { public void open() { System.out.println("sound...open"); } public void close() { System.out.println("sound...close"); }}
利用反射实现:
1)主板可以插入声卡网卡等,声卡等要实现个接口(PCI),这个接口是和主板关联的,比如主板中有public void usePCI(PCI p)方法,那么这个方法就能实现PCI中的功能(为简单起见,这个接口只有open、close功能)。
2)需要读配置文件用Properties类中的load方法加载文件到集合中,配置文件中放的是设备:类名,这样就可以通过遍历这个集合,将类名取出,利用类名创建对象p,然后再用主板的usePIC(p),就可以将这个设备运行起来了。
特别提示:若配置文件为空,则集合.size()==-1,则主板上没有可运行的,只能运行主板或者其他的接口。若需要添加PCI设备,只需要在配置文件中加入类名即可,不用修改主板代码(因为集合长度+1了),提高了程序的扩展性
package com.Car1;import java.io.*;import java.util.*;public class mainBoard { public void run() { System.out.println("main.......run"); } public void usePCI(PCI p)//无论是插入什么设备,只要是设备符合PCI这个接口,都有两个方法可用 { p.open(); p.close(); } public static void main(String[] args)throws Exception { mainBoard mb=new mainBoard(); mb.run(); FileInputStream fis=new FileInputStream("e:\\pci.prop");//配置文件,格式是设备:类名 Properties prop=new Properties(); prop.load(fis);//将流中对象加载进集合 for(int x=0;x<prop.size();x++) { String className=prop.getProperty("pci"+(x+1));//获取类名 Class clazz=Class.forName(className); PCI p=(PCI)clazz.newInstance(); mb.usePCI(p); } fis.close(); }}package com.Car1;public interface PCI { public void open() ; public void close();}package com.Car1;public class soundCard implements PCI{ public void open() { System.out.println("sound...open"); } public void close() { System.out.println("sound...close"); }}package com.Car1;public class netBoard implements PCI { public void open() { System.out.println("net...open"); } public void close() { System.out.println("net...close"); }}
- (104)反射:获取Class的对象、构造函数、字段、方法。反射实例练习
- 无法反射到想要的构造函数时该如何根据Class对象构造Class实例?
- 通过反射可以获取Class的构造方法 通过构造方法创建对象
- 反射获取对象实例的字段信息和字段值
- Java反射---Class对象,获得类的方法、成员变量和构造函数信息
- java反射学习笔记(3)---使用Class来获取方法、成员变量、构造函数信息
- 反射详解-通过Class实例化具体类的对象(无参数构造)
- 四种获取Class对象的方法 Java反射机制
- java反射之——获取Class对象的方法
- 反射获取Class对象的四种方法
- java反射(2)获取Class对象的三种方法
- 反射获取构造方法并创建对象
- 反射(构造方法,方法,main,字段)
- java反射机制 以及通过反射获得类的变量字段,方法,构造函数
- java反射机制 以及通过反射获得类的变量字段,方法,构造函数
- java反射之Class类、构造器、方法、字段、数组
- 反射的应用、获取Class类实例
- Class对象使用实例,反射的基本原理
- Servlet常用的六个对象
- 求二叉树结点最大距离
- 常用Socket函数详解
- 高斯相关内容
- 【计算机网络】网络诊断工具ping的模拟实现之具体细节
- (104)反射:获取Class的对象、构造函数、字段、方法。反射实例练习
- asp.net4.0网站开发与项目实战—学习笔记1
- java高级特性之--自动拆装箱和枚举
- Working with Linear Models
- linux命令之 tree 命令
- 集群
- HDU 3853 概率DP 解题报告
- ToLua学习笔记,通信(二)
- 源码分析:SharedPreferences实现