反射(含路径问题)部分笔记课案_第1页
反射(含路径问题)部分笔记课案_第2页
反射(含路径问题)部分笔记课案_第3页
反射(含路径问题)部分笔记课案_第4页
反射(含路径问题)部分笔记课案_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、源文件来自y2笔记反射(reflect)反射即将class类中的所有的成员映射为相应的对象。要学习反射那么需要先了解和掌握以下几个类:类描述class描述所有的class文件的共性filed描述的是class文件的中的属性的共性constructor描述的是class文件中的构造函数的共 性method描述的是class文件中的函数的共性1.获取指定类的class对象方式一:类名.class方式二:对象名.getclass()方式三:forname(string classname)该方法是 class类的静态方法推荐举例1: 获取字符串类的 class对象。public static voi

2、d main(string口 args)throws exception /使用不同的方式会过去 class对象class clazz1 = string.class ;class clazz2 = new string( "zhangsan" ).getclass();/参数必须指定类的全名(类的全限定名)class clazz3 = class.forname ( "java.lang.string");/ class文件时候独一无二的,那么 class对象也应该是单例的system. out .println(clazz1 = clazz2);/

3、truesystem. out .println(clazz2 = clazz3);/ true以上的方式都可以获取指定类的class对象,在实际的开发中到底要使用哪一一般的情况下我们都需要在不知道类名的情况下获取类的class对象并进而获取类中包含的成员进行操作。大家可以参考tomcat的一个基本的 server.xml文件<resource name="userdatabase" auth="container"type="org.apache.catalina.userdatabase”description="user

4、database that can be updated and saved" factory="org.apache.catalina.users.memoryuserdatabasefactory"pathname="conf/tomcat-users.xml” />2.将class对象中的属性进行反射为filed对象 常用的获取属性字段的方法方法field口 getdeclaredfields()描述获取所有声明的字段数组对象field getfields()fieldgetdeclaredfield(string获取所有的声明的共有字段数组

5、对象 获取指定名称的声明的字段对象name)field getfield(string name)获取指定名称的声明的共有字段对象举例1:获取所有的声明字段数组对象public static void main(string口 args)throws exception / 获取shape类的class对象 class clazz = class.forname ("cn.sve.bean.shape" );/获取所有的属性field 口 fs = clazz.getdeclaredfields(); system. out .println(fs. length );/

6、2/获取所有共有的属性 fs = clazz.getfields();system. out .println(fs. length );/ 1/获取指定名字的私有的属性 field field = clazz.getdeclaredfield("x");system. out .println(field);/获取指定名字的共有的属性 field = clazz.getfield("y");system. out .println(field);举例2:调用field类的方法进行字段对象的操作。throws exception public stati

7、c void main(string口 args)/ 获取shape类的class对象class clazz = class.forname ( "cn.sve.bean.shape" );/获取所有的属性field 口 fs = clazz.getdeclaredfields();system. out .println(fs. length );/ 2/获取所有共有的属性fs = clazz.getfields();system. out .println(fs. length );/ 1shape shape = new shape(); / 20/获取指定名字的私有

8、的属性field field = clazz.getdeclaredfield("x");system. out .println(field);system. out .println( /获取x的属性值,彳 field.setaccessible( system. out .println( / 设置x的属性值 field.set(shape, 20); system. out .println("属性名:"+field.getname();/操作私有的属性x需要暴力的反射true );”设置之前的 x值:"+field.get(shape

9、);”设置之后的 x值:"+field.get(shape);/获取指定名字的共有的属性field = clazz.getfield("y");system. out .println(field);/给属性y进行设置值system. out .println( "属性名:"+field.getname();/获取设置属性值之前的值system. out .println("设置之前的 y值:"+field.get(shape);/20 field.set(shape,30);/ 30system. out .println

10、("设置之后的 y值:"+shape. y);/ 30 以上的代码可以通过程序进行反射类中的属性字段并操作,但是没有进行静态属 性的反射和操作。举例3:反射静态的成员属性。throws exception public static void main(string口 args)/ 获取shape类的class class clazz = class./获取共有的静态属性field field = clazz.getfield(对象forname("cn.sve.bean.shape");system. field.set( system.outout.

11、println( null , 40); .println("z");”设置之前的z值:"+field.get("设置之后的z值:"+field.get(null );null );3 .将class对象中的方法进行反射为method对象。public static void main(string口 args)throws exception / 获取shape类的class对象class clazz = class.forname ( "cn.sve.bean.shape" );/获取所有的声明的方法method ths

12、 = clazz.getdeclaredmethods();system. out .println(ths. length ); / 2/获取私有的带参数的sayhello 方法method sayhello = clazz.getdeclaredmethod("sayhello string. class 匚system. out .println(sayhello);/调用私有的方法sayhello.setaccessible(true );sayhello.invoke( new shape(), "zhangsan" );/获取所有的共有的方法ths =

13、 clazz.getmethods();system. out .println(ths. length ); / 10/获取带参数的共有的方法method greet = clazz.getdeclaredmethod("greet" ,string. class );system. out .println(greet);/方法的调用greet.invoke( new shape(), "zhangsan" );4 .将class对象中的构造函数进行反射为constructor对象。public static void main(string口 ar

14、gs)throws exception / 获取shape类的class对象class clazz = class.forname ("cn.sve.bean.shape" );/获取所有的声明的构造函数constructor cons = clazz.getdeclaredconstructors();system. out .println(cons. length );/ 3/获取带参数的私有的构造函数对象 constructor con =clazz.getdeclaredconstructor(int . class , int . class); system.

15、 out .println(con); /暴力反射私有的构造函数创建对象 con.setaccessible( true ); shape myshape = (shape) con.newinstance(400,500); system. out .println(myshape.getx()+"," +myshape. y);/获取所有的共有的构造函数 cons = clazz.getconstructors(); system . out .println(cons. length );/ 2con = clazz.getconstructor(int . clas

16、s );system. out .println(con); /调用构造函数创建对象 shape shape = (shape) con.newinstance(100); system. out .println(shape.getx(); 面试题:请简单的叙述出你所可以创建的对象的几种方式? 第一种:直接使用new关键字 第二种:construnctor.newinstance 第三种:枚举 第四种:单例、工厂模式内省(introspect)其实在以上的反射技术体验中我们发现其实反射的对象一般是一个具有特定功 能的一个类。引入一个基本的概念:javabean如果一个类提供了封装好的属性、构

17、造函数(无参数)、共有的get和set方法以及简单的业务逻辑方法那么将这样的一个类称之为javabeangfeo对于一个javabean的操作无非就是给属性值进行操作或函数的调用。使用反射比较繁琐,那么 sun就提供了内省的技术方便大家进行 javabea卷的 操作。类描述beaninfo对javabean!行描述的接口introspector描述所有的javabean的成员类propertydescriptor描述的是javabean的属性类举例1:使用属性描述器类操作javabeanh性。创建一个book的javabean类public class book privatestringna

18、me;/ nullprivatestringauthor ;/ nullprivatedoubleprice ;/ / 0.0privatedatedate ;/ nullpublicbook() super ();public book(string name, string author, double price, date date) super ();this . name = name;this . author = author;this . price = price;this . date = date;/ 省略get和set方法 使用内省技术进行简单的属性的操作。publi

19、c static void main(string口 args)throws exception/获取一个属性的描述器对象就相当于获取了属性的名、set和get方法propertydescriptor pd =newpropertydescriptor( "name" ,book. class ) ; / 获取set方法 method set = pd.getwritemethod(); /调用该方法设置属性的值 book book = new book(); system. out .println( "设置前获取 name 属性值:"+book.ge

20、tname();set.invoke(book, "javase 进阶”);system. out .println( "设置后获取 name 属性值:"+book.getname();/ 获取get方法method get = pd.getreadmethod();system. out .println(get.invoke(book,null );以上的代码每次都只能操作一个属性,这样就比较繁琐。可以使用其他的类直接 获取所有的属性描述器通过循环来直接操作。public static void main(string口 args)throws excepti

21、on/ 获取指定的beaninfo 对象beaninfo info = introspector.getbeaninfo (book. class );/获取book类中的所有的属性的描述器对象propertydescriptor口 pds = info.getpropertydescriptors();/输出长度system. out .println(pds. length );/查看数组的第一个属性描述器是谁propertydescriptor pd = pds0;/作者system. out .println(pd.getname();book book = new book();/给

22、书设置作者信息pd.getwritemethod().invoke(book,"zhangsan" );system. out .println(pd.getreadmethod().invoke(book, null » 总结:其实发现在使用内省进行属性操作的时候要结合反射一起使用。 面试题:一个javabean中为什么必须要提供一个无参数的构造函数? 原因一:为了可以做父类。原因二:为了可以使用反射创建对象。beanutils 工具在实际的开发中我们经常需要将用户的录入的数据进行封装为对象,那么如果使用反射和内省技术就会变得吃力。因此本节主要给大家讲解一个开源

23、的操作 javabea巾勺一个工具即beanutils。下载:beanutils-1.8.0.zipcommons-logging.jar包的引入:在项目中创建一个文件夹如libs,然后将整个项目需要的第三方的jar包可以直接 拷贝带该目录,随后打开该目录全选 右键 build path add path 看到奶瓶 子即可举例1:使用beanutils工具封装用户提交的数据。public staticvoid main(string口 args)throws exception /模拟用户的输入的数据如下string name ="xml基础”

24、;string author ="zhangsan" ;string price ="99.99"string date = "2016-07-07"book book =new book();/任务是将以上的属性设置给指定的book对象beanutils.setproperty (book,"name" , name);beanutils.setproperty (book,"author" , author);beanutils.setproperty (book,"price&q

25、uot; ,price );/查看属性是否封装好 system. out .println(book); 发现使用上面的代码可以省略基本数据类型的转型的问题。进而提高代码的开发效率。举例2:自定义一个类型转换器类。public static void main(string口 args)throws exception /模拟用户的输入的数据如下string name ="xml基础”;string author ="zhangsan" ;string price ="99.99"string date ="2016-07-07&qu

26、ot;book book =new book();/*注册一个自己的转换器converter指定具体的转换器clazz遇到什么类型调用上面的转换器*/convertutils. register ( new converter() /回调方法 ©override public object convert(class type, object value) if(value =null )returnnull ;/ 转换为stringstring data = (string)value;/将指定格式的字符串转换为datesimpledateformat format =newsim

27、pledateformat( "yyyy-mm-dd" );date date = null ;try date = format.parse(data);return date; catch (parseexception e) e.printstacktrace(); return null ;,date. class );/任务是将以上的属性设置给指定的book对象beanutils.setproperty(book,"name" , name);beanutils.setproperty(book,"author" , aut

28、hor)beanutils.setproperty(book,"price" ,price );beanutils.setproperty(book,"date" ,date );/查看属性是否封装好system. out .println(book);如果每次遇到一个复杂类型都需要自定义转换器,那样的话实在麻烦。大家看在 开发的时候可以先查看该接口是否提供了有效的实现类。convertutils.register(new datelocaleconverter(), date.class);其实真正的封装好的数据需要存储在数据库中,那么 javabea

29、n的数据类型应该 和数据库的数据类型保持一致,那么在声明持久化 javabean的时候需要全部为 数据库的基本数据类型。因此大家在javabean中需要导入的是java.sql.date类,这样就直接可以将日期自 动转换了。举例3:实现封装好的javabeam象的属性拷贝。/实现属性封装数据的一个拷贝book copy = new book();system. out .println(copy);propertyutils. copyproperties (copy, book);system. out .println(copy);思考:如果使用beanutils封装用户的数据,那么也就是

30、一个一个设置啊?岂不 是也很麻烦?其实在真是的环境中我们可以直接获取用户提交的所有的数据信息,只需要进行遍历即可,但是为了方便快速的设置,那么可以将 javabean中的属性名和用户 提交的数据名保持一致。框架体验其实所谓的框架就是通过一些配置文件来将需要运行的模块以及类、方法在软件启动的时候自动运行。如果将需要运行类以及模块配置在文件中那么便于后期的 一个维护。1 .创建一个配置文件如下run=cn.sve.service.userserviceme=autorunvalue=jack,lucy2 .创建两个实现接口的服务类userservice.javapublic class users

31、ervice implements service/提供自动运行的方法public void autorun(string names)/使用,号切割用户列表string 口 ns = names.split(",");/遍历for (string name:ns)system. out .println( "姓名:"+name);startservice.javapublic class startservice implements service /提供自动运行的方法public void autorun(string names)/使用,号切割用

32、户列表string 口 ns = names.split(",");/遍历for (string name:ns)system. out .println(name);以上的两个类拥有共同的方法因此可以抽取为接口service.javapublic interface service /提供自动运行的方法 public abstract void autorun(string names);throws exception3 . 直接编写一个main.java进行逻辑处理 public class main public static voidmain(string口 ar

33、gs)/ 1.获取配置信息properties ps =new properties。;/ 2.装载文件数据ps.load( new fileinputstream(/ 3.获取数据string str_clazz = ps.getproperty(string str_method = ps.getproperty(string str_value = ps.getproperty(/ 4.反射获取class对象new file( "sve.ini""run");"me");"value"););class cl

34、azz = class.forname (str_clazz);/ 5.创建对象null );null );constructor con = clazz.getconstructor(service service = (service)con.newinstance(/ 6.调用相关的方法method method = clazz.getmethod(strmethod, string. method.invoke(service, str value);这样的话就基本的实现了一个框架的模拟, 大家以后就可以同配置文件的形式修 改程序运行的服务类了。javase的路径问题举例1:读取项目根目录下的数据。privatestatic void readroot()throws filenotfoundexception,ioexceptionbufferedreader br =newbufferedreader(new filereader(new file( "sve.txt");string l

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论