Java反射技术应用广泛,其能够配置:类的全限定名,方法和参数,完成对象的初始化,设置是反射某些方法。可以增强java的可配置性。

1.1 通过反射构建对象(无参数):

  例如我们使用 ReflectServiceImpl 类讲解这个例子

  1. public class ReflectServiceImpl {
  2. public void sayHello(String name){
  3. System.out.println("hello"+name);
  4. }
  5. }

我们通过反射的方法去构建它。

  1. public ReflectServiceImpl getInstance(){
  2. ReflectServiceImpl object=null;
  3. try {
  4. object=(ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();
  5. } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
  6. e.printStackTrace();
  7. }
  8. return object;
  9. }

其中第4行:object=(ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();

是给类加载器注册一个类ReflectServiceImpl的权限定名,之后通过newInstance方法初始化一个类对象。

1.2 通过反射构建对象(类的构造器中带有参数):

我们使用ReflectServiceImpl2这个类去理解:

  1. public class ReflectServiceImpl2 {
  2. private String name;
  3. public ReflectServiceImpl2(String name) {
  4. this.name=name;
  5. }
  6. public void sayHello(String name){
  7. System.out.println("hello"+name);
  8. }
  9. }

此时 ReflectServiceImpl2的构造器带有参数  public ReflectServiceImpl2(String name){xxxx};

此时我们该如何利用反射生成对象呢?只需要在类加载器注册的使用getConstructor(参数)方法。其中参数是我们构造器中的参数的类型。代码如下:

  1. public ReflectServiceImpl2 getInstance(){
  2. ReflectServiceImpl2 object=null;
  3. try {
  4. object=(ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2")
  5. .getConstructor(String.class).newInstance("张三");
  6. } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | InvocationTargetException |NoSuchMethodException e) {
  7. e.printStackTrace();
  8. }
  9. return object;
  10. }

如4、5行所示:

  先通过forName加载到类的加载器。然后通过getConstructor方法,它的参数可以是多个,这里定义String.class,意为有且只有一个参数类型为String 的构建方法。通过这个方法可以对重名方法进行排除,此时再用newInstance方法生成对象,只是newInstance方法也多了一个参数“张三”而已。实际上就等于object=new ReflectServiceImpl2("张三").只是利用了反射来生成对象而已。

1.3 反射方法

  在使用反射方法之前需要先获取对象,得到了方法才能够去反射。

我们使用 ReflectServiceImpl 类为例。

ReflectServiceImpl代码:

  1. public class ReflectServiceImpl {
  2. public void sayHello(String name){
  3. System.out.println("hello"+name);
  4. }
  5. }

调用方法:

  1. public Object reflect(){
  2. ReflectServiceImpl object=null;
  3. Object returnObj=null;
  4. //反射生成对象
  5. try {
  6. object = (ReflectServiceImpl) Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();
  7. //反射生成方法并调度
  8. Method method = object.getClass().getMethod("sayHello", String.class);
  9. returnObj= method.invoke(object, "张三");
  10. }catch( ClassNotFoundException| NoSuchMethodException| InvocationTargetException| IllegalAccessException| InstantiationException e ) {
  11. e.printStackTrace();
  12. }
  13. return returnObj;
  14. }

当有具体对象 object(类型为ReflectServiceImpl),而不知道具体是哪个类的时候,也可以使用object.getClass().getMethod("sayHello", String.class);来替代它,其中第一个参数是方法的名称,第二个参数是参数类型,是一个列表,多个参数可以继续编写多个类型,这样便能够获得反射的方法对象。反射方法时运用 method.invoke(object, "张三");调用的,第一个参数为object,就是确定用哪个对象调用方法,而“张三”是参数,这就等同于object.sayHello("张三");若存在多个参数可以写成Method.invoke(target,obj1,obj2.obj3...),这些要根据对象的具体方法来确定。

1.4 测试

以ReflectServiceImpl为例:

  1. package com.lean.reflect;
  2. import java.lang.reflect.InvocationTargetException;
  3. import java.lang.reflect.Method;
  4. public class ReflectServiceImpl {
  5. //属性
  6. private String name;
  7. //默认的构造方法
  8. public ReflectServiceImpl() {
  9. super();
  10. }
  11. //带参数的构造方法
  12. public ReflectServiceImpl(String name) {
  13. this.name=name;
  14. }
  15. //方法 sayHelo
  16. public void sayHello(String name){
  17. System.out.println("hello "+name);
  18. }
  19. //调用方法
  20. public Object reflect(){
  21. ReflectServiceImpl object=null;
  22. Object returnObj=null;
  23. //反射生成对象
  24. try {
  25. object = (ReflectServiceImpl) Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();
  26. //反射生成方法并调度
  27. Method method = object.getClass().getMethod("sayHello", String.class);
  28. returnObj= method.invoke(object, "张三");
  29. }catch( ClassNotFoundException| NoSuchMethodException| InvocationTargetException| IllegalAccessException| InstantiationException e ) {
  30. e.printStackTrace();
  31. }
  32. return returnObj;
  33. }
  34. //获取对象
  35. public ReflectServiceImpl getInstance(){
  36. ReflectServiceImpl object=null;
  37. try {
  38. object=(ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();
  39. } catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
  40. e.printStackTrace();
  41. }
  42. return object;
  43. }
  44. //测试
  45. public static void main(String[] args) {
  46. ReflectServiceImpl rsl= new ReflectServiceImpl();
  47. rsl.reflect();
  48. }
  49. }

效果图:

java反射构建对象和方法的反射调用的更多相关文章

  1. Java中类,对象,方法的内存分配

    Java中类,对象,方法的内存分配 以下针对引用数据类型: 在内存中,类是静态的概念,它存在于内存中的CodeSegment中. 当我们使用new关键字生成对象时,JVM根据类的代码,去堆内存中开辟一 ...

  2. Java反射【三、方法的反射】

    获取一个类下的所有方法 可以获取类类型后,获取到所有方法及相关信息 Method[] ms = c.getMethods(); 获取方法列表(public) Method[] ms = c.getDe ...

  3. java——类、对象、方法

    一.类 1.Java语言把一组对象中相同属性和方法抽象到一个Java源文件就形成了类. 一个java文件可以有多个类,但是每一个类都会生成一个class字节码文件. 如果class 前加public ...

  4. Java虚拟机构建对象过程小记

    Java对象的内存分布 Java对象的构建 Java程序中,新建对象,除了常见的new语句之外,还可以通过反射机制.Object.clone方法.反序列化以及Unsafe.allocateInstan ...

  5. Java笔记:对象,方法,类

    1.数据类型(类) 对象名; 这里要求数据类型必须为复合数据类型,基本数据类型声明的结构只能称为变量,而不能称为对象. 对象的初始化 对象名= new 构造方法(参数); 2.方法: 访问控制符 [修 ...

  6. Java中的对象Object方法之---wait()和notifiy()

    这一篇咋们继续,接着来介绍wait()和notify()方法,我们都知道这两个方法和之前介绍的方法不太一样,那就是这两个方法是对象Object上的,不属于Thread类上的.我们也知道这两个方法是实现 ...

  7. java中获得对象的方法

  8. java的应用包的方法,及调用类里面函数的原理

    selenium官网下载的selenium包 包导入eclipse 见:https://www.cnblogs.com/kaibindirver/p/10674604.html 代码

  9. 应用反射写的tostring方法

    应用反射写的tostring方法 应用反射写的tostring方法,方便以后查询 代码 package com.chzhao.reflecttest; import java.lang.reflect ...

随机推荐

  1. IdHTTP设置SSL证书,乱码问题也解决了

    要跟银行做接口,需要使用delphi来post数据,但对方提供的是https开头的网址,需要使用证书,对方已提供证书了,但是还是调用不成功,使用的是idhttp和TIdSSLIOHandlerSock ...

  2. 浅议Delphi中的Windows API调用(举的两个例子分别是String和API,都不错,挺具有代表性)

    浅议Delphi中的Windows API调用http://tech.163.com/school • 2005-08-15 10:57:41 • 来源: 天极网为了能在Windows下快速开发应用程 ...

  3. c# RedisHelper

    使用redis组件如下,至于为什么使用3.9版本,是因为4.0开始商业了,限制了次数 ServiceStack.Common" version="3.9.70"Servi ...

  4. 利用批处理自动创建schtasks系统任务

    通过批处理自动创建schtasks系统任务,把下列代码保存成bat文件,放到要执行的文件的同级目录即可. @echo on set curpath=%cd%c:cd %systemroot%schta ...

  5. 为QNetworkAccessManager添加超时提醒(自己记录一段时间里的下载字节数,用定时器去定期检测,从而判断是否超时)

    在做更新,在测试异常的时候,在下载过程中,发现如果直接系统禁用了网络,会报错误,可以捕获.但是如果是第三方软件限制程序联网,问题来了. 程序会一直在那里等待,没有异常,也不发送QNetworkAcce ...

  6. C语言实现常用数据结构——堆

    #include<stdio.h> #include<stdlib.h> #define CAPACITY 20 /*堆有两个性质: * 1.结构性:堆必须是一颗完全二叉树 * ...

  7. ios开发系列之内存泄漏分析(下)

    接上篇,本篇主要讲解通知和 KVO 不移除观察者.block 循环引用 .NSThread 和 RunLoop一起使用造成的内存泄漏. 1.通知造成的内存泄漏 1.1.ios9 以后,一般的通知,都不 ...

  8. 【时间工具】整理下java时间换算专题

    首先总结了一下日期转换基础,最常用的两个工具类Date与calender,转换方法如下: package com.zzt.spider; import java.text.SimpleDateForm ...

  9. Spring事物管理简介 (转)

    一.事物1.什么是事物 事物指的是逻辑上的一组操作,这组操作要么全部成功,要么全部失败 2.事物的特性 原子性:事物是一个不可分割的工作单位,事物中的操作要么都发生,要么都不发生 一致性:事物前后数据 ...

  10. PHP输出缓冲及其应用

    缓冲(buffer)是为了协调吞吐速度相差很大的设备之间数据传送而采用的技术,用来存放缓冲数据的区域叫缓冲区,在计算机科学领域,当数据从一个地方传送到另一个地方时,缓冲区被用来临时存储数据.与缓冲相似 ...