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

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

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

 public class ReflectServiceImpl {
public void sayHello(String name){
System.out.println("hello"+name);
}
}

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

 public ReflectServiceImpl getInstance(){
ReflectServiceImpl object=null;
try {
object=(ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}

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

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

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

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

 public class ReflectServiceImpl2 {
private String name;
public ReflectServiceImpl2(String name) {
this.name=name;
}
public void sayHello(String name){
System.out.println("hello"+name);
}
}

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

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

 public ReflectServiceImpl2 getInstance(){
ReflectServiceImpl2 object=null;
try {
object=(ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2")
.getConstructor(String.class).newInstance("张三");
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | InvocationTargetException |NoSuchMethodException e) {
e.printStackTrace();
}
return object;
}

如4、5行所示:

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

1.3 反射方法

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

我们使用 ReflectServiceImpl 类为例。

ReflectServiceImpl代码:

 public class ReflectServiceImpl {
public void sayHello(String name){
System.out.println("hello"+name);
}
}

调用方法:

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

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

1.4 测试

以ReflectServiceImpl为例:

 package com.lean.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectServiceImpl {
//属性
private String name;
//默认的构造方法
public ReflectServiceImpl() {
super();
}
//带参数的构造方法
public ReflectServiceImpl(String name) {
this.name=name;
}
//方法 sayHelo
public void sayHello(String name){
System.out.println("hello "+name);
}
//调用方法
public Object reflect(){
ReflectServiceImpl object=null;
Object returnObj=null;
//反射生成对象
try {
object = (ReflectServiceImpl) Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();
//反射生成方法并调度
Method method = object.getClass().getMethod("sayHello", String.class);
returnObj= method.invoke(object, "张三");
}catch( ClassNotFoundException| NoSuchMethodException| InvocationTargetException| IllegalAccessException| InstantiationException e ) {
e.printStackTrace();
}
return returnObj;
}
//获取对象
public ReflectServiceImpl getInstance(){
ReflectServiceImpl object=null;
try {
object=(ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance();
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
e.printStackTrace();
}
return object;
}
//测试
public static void main(String[] args) {
ReflectServiceImpl rsl= new ReflectServiceImpl();
rsl.reflect();
}
}

效果图:

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. 一份React-Native学习指南

    直击现场 学习React-Native过程中整理的一份学习指南,包含 教程.开源app和资源网站等,还在不断更新中.欢迎pull requests! React-Native学习指南 本指南汇集Rea ...

  2. 配置我的Ubuntu Server记(包括桌面及VNC,SSH,NTP,NFS服务) good

    跟老板申请买了一台配置相对较好的计算机回来做GPU计算,当然,不能独享,所以做成服务器让大家都来用. 这篇日志用来记录配置过程中遇到的一些问题,以方便下次不需要到处谷歌度娘. 安装Server版系统 ...

  3. QT父子窗口事件传递与事件过滤器(讲了一些原理,比较清楚)

    处理监控系统的时候遇到问题,在MainWidget中创建多个子Widget的时候,原意是想鼠标点击先让MainWidget截获处理后再分派给子Widget去处理,但调试后发现如果子Widget重新实现 ...

  4. 从 docker 到 runC

    笔者在前文<RunC 简介>和<Containerd 简介>中分别介绍了 runC 和 containerd.本文我们将结合 docker 中的其它组件探索 docker 是如 ...

  5. 线性表List

    数组array是基本的数据结构,但它的功能有限,线性表list可以认为是扩展了功能的数组.可以自动调整大小.添加和删除元素不需要其他元素移位. 根据指针数量和指向的不同,线性表分为单向链表.双向链表和 ...

  6. 如何使用Vue.js来搭建一个后台管理系统

    目录 使用的技术 基础但不好版 1.初始化项目 2.实现初始页内容自定义 3.使用路由 原始代码 自建页面 修改路由 4.测试路由跳转 补充 子路由版 嵌套router-view 定义子路由 修改菜单 ...

  7. Servlet 3.0异步特性初探

    Servlet 是 Java 为了编写服务端程序而定义的一个接口规范,在 Servlet 3.0 以后支持了异步的操作. 最近项目添加了一个代码热部署的功能,在客户端输入信号,信号到达 Web 服务器 ...

  8. .NET中生成水印更好的方法

    .NET中生成水印更好的方法 为了保护知识产权,防止资源被盗用,水印在博客.网店等场景中非常常见. 本文首先演示了基于System.Drawing.Image做正常操作.然后基于Direct2D/WI ...

  9. 高并发 Nginx+Lua OpenResty系列(3)——模块指令

    Nginx Lua 模块指令 Nginx共11个处理阶段,而相应的处理阶段是可以做插入式处理,即可插拔式架构:另外指令可以在http.server.server if.location.locatio ...

  10. PWN菜鸡入门之栈溢出(1)

    栈溢出 一.基本概念: 函数调用栈情况见链接 基本准备: bss段可执行检测: ​ gef➤ b main Breakpoint at . gef➤ r Starting program: /mnt/ ...