Java中反射机制和作用详解

前言

很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象。

那么接下来大师就带你们了解一下反射是什么,为什么要学习反射?

下面我们首先通过一个实例来说明反射的好处:

方法1、不用反射技术,创建用户对象,调用sayHello方法

1.1 我们首先创建一个User类

package com.dashi;

/**
 * Author:Java大师
 * User对象,包含用户的id和姓名以及sayHello方法
 */
public class User {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String sayHello(String who) {
        return who+ "{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

1.2 创建测试用例

package com.dashi;

import org.junit.Test;

/**
 * 创建Juinit测试对象
 */
public class Test01 {

    @Test
    public void test01(){
        User user = new User();
        user.setId(1);
        user.setName("Java大师");
        //调用sayHello方法
        System.out.println(user.sayHello("user1"));
    }
}

1.3运行结果如下,打印出sayHello结果:

user1{id=1, name='Java大师'}

Process finished with exit code 0

方法2、通过反射技术,创建用户对象,调用sayHello方法

2.1 调用测试用例

@Test
    public void test02(){
        try {
            //创建用户对象字符串
            String obj = "com.dashi.User";
            //通过用户对象字符串加载类
            Class clz = Class.forName(obj);
            //通过newInstance方法,创建用户对象
            User user = (User)clz.newInstance();
            user.setId(2);
            user.setName("Java大师2");
            //调用sayHello方法
            System.out.println(user.sayHello("user2"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

2.2 运行结果如下,打印出sayHello结果:

user1{id=1, name='Java大师'}
user2{id=2, name='Java大师2'}

Process finished with exit code 0

通过两者以上对比,发现方法1和方法2都能创建用户对象,并调用sayHello方法,并且打印的结果都正确。但是方法2比方法1先进的地方是方法2针对字符串编程,方法1针对实体类编程。

那么针对字符串编程有什么好处呢,小伙伴们耐心接着往下看:

我们通过一个Dao层来演示下针对字符串编程的好处:

假设我们有一个IUserDao接口,里面有一个load方法,代码如下:

package com.dashi;

public interface IUserDao {
    public void load();
}

有两个实现类来实现该IUserDao接口,实现类如下:

package com.dashi;

/**
 * A实现类
 */
public class AUserDao implements IUserDao{
    @Override
    public void load() {
        System.out.println("这是AUserDao");
    }
}
package com.dashi;

/**
 * B实现类
 */
public class BUserDao implements IUserDao{
    @Override
    public void load() {
        System.out.println("这是BUserDao");
    }
}

方法3、不通过反射技术,创建IUserDao,调用load方法

@Test
    public void testDao01(){
        IUserDao userDao = new AUserDao();
        userDao.load();
    }

打印结果如下:

这是AUserDao

Process finished with exit code 0

方法4、通过反射技术,创建IUserDao,调用load方法

@Test
    public void testDao02(){
        try {
            //创建接口实现类字符串
            String dao_str = "com.dashi.AUserDao";
            //通过类加载的方式创建IUserDao
            IUserDao userDao = (IUserDao) Class.forName(dao_str).newInstance();
            //调用load方法
            userDao.load();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

打印结果如下:

这是AUserDao
这是AUserDao

Process finished with exit code 0

通过类加载的方式,我们也创建了IUserDao对象,调用了load方法,和方法3的运行结果一样

方法5、通过反射技术,创建IUserDao,调用load方法

@Test
    public void testDao03(){
        try {
            //创建接口实现类字符串
            String dao_str = "com.dashi.BUserDao";
            //通过类加载的方式创建IUserDao
            Class clz = Class.forName(dao_str);
            IUserDao userDao= (IUserDao)clz.newInstance();
            //创建调用方法字符串
            String mm = "load";
            //创建method对象
            Method method =  clz.getMethod(mm);
            //调用通过反射调用invoke方法
            method.invoke(userDao);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

运行结果如下:

这是AUserDao
这是AUserDao
这是BUserDao

Process finished with exit code 0

通过method.invoke方法也可以实现load方法的调用

方法5比方法4和方法3更加灵活,不需要知道AUserDao和BUserDao实体类,只提供类的字符串和类的方法名称,通过反射就可以实现方法的调用

实战中的实际意义

假设我们的Dao层,从mysql迁移导oracle,SQL server等

运用反射技术,通过字符串编程,那么我们不需要进行Dao层实体类的更改,只需要改动我们的字符串名字就可以进行Dao层的更新。比如:

1、不通过反射技术,我们需要修改实现类中的AUserDao改为BUserDao
IUserDao userDao = new AUserDao();
userDao.load();
``如果有几百个Dao,我们需要修改几百次``
``
2、运用发射技术通过字符串编程,我们可以把字符串定义在properties文件中,通过修改properties文件中的配置即可实现Dao的更新
 //创建接口实现类字符串
 String dao_str = "com.dashi.AUserDao"; //可以改写为:String dao_str = PropertyUtil.get("dao");
 //通过类加载的方式创建IUserDao
 IUserDao userDao = (IUserDao) Class.forName(dao_str).newInstance();
 //调用load方法
 userDao.load();

这就是反射技术的实际运用,通过以上实例就可以看出字符串编程和通过实现类编程的最大的区别和实际的意义

并且通过反射技术可以使我们的编程更加灵活

灵活运用反射技术,我们可以设计出更加灵活的框架哦~

总结

到此这篇关于Java中反射机制和作用详解的文章就介绍到这了,更多相关Java反射机制内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Java通过反射机制动态设置对象属性值的方法

    /** * MethodName: getReflection<br> * Description:解析respXML 在通过反射设置对象属性值 * User: liqijing * Date:2015-7-19下午12:42:55 * @param clzzName * @param respXML * @return * @throws ClassNotFoundException * @throws DocumentException * @throws IllegalArgumentE

  • Java反射机制详解

    本文较为详细的分析了Java反射机制.分享给大家供大家参考,具体如下: 一.预先需要掌握的知识(java虚拟机) java虚拟机的方法区: java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存储被装载的类 的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中.这些信息主要包括: 1.这个类型的全

  • java反射机制示例详解

    1.什么是反射?一个类有多个组成部分,例如:成员变量,方法,构造方法等.反射就是加载类,并解剖出类的各个组成部分. 2.加载类java中有一个Class类用于代表某一个类的字节码.Class类既然代表某个类的字节码,那就要提供加载某个类字节码的方法:forName().   此方法用于加载某个类的字节码到内存中,并使用class对象进行封装.另外2种得到class对象的方式:类名.class对象.getClass() 先创建一个简单的Person类 复制代码 代码如下: public class

  • java 利用反射机制,获取实体所有属性和方法,并对属性赋值

    一个普通的实体Person: private int id; private String name; private Date createdTime; ... //其它字段 // get set方法 ............... 现在需要把通过webService传过来的实体Person里面的所有字段的null值,换成"" 实现思路: 1.获取实体的所有字段,遍历 2.获取字段类型 3.调用字段的get方法,判断字段值是否为空 4.如果字段值为空,调用字段的set方法,为字段赋值

  • 利用java反射机制调用类的私有方法(推荐)

    试想一下,如果你可以轻易地调用一个类的私有方法,那么是不是说你的封装都失效了?最近在看java的反射机制,发现居然可以利用java的反射机制去调用其他类的私有方法,至于这能干什么,那就见人见智了.. 我写的一段简易实例代码如下: import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author thomaslwq * @version 创建时间:Sep 4, 201

  • Java反射机制的学习总结

    一.什么是反射机制 简单的来说,反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息. 二.哪里用到反射机制 有些时候,我们用过一些知识,但是并不知道它的专业术语是什么,在刚刚学jdbc时用过一行代码, Class.forName("com.mysql.jdbc.Driver.class").newInstance();但是那时候只知道那行代码是生成驱动对象实例,并不知道它的具体含义.听了反射机制这节课后,才知道,原来这

  • Java反射机制的实现详解

    很多主流框架都使用了反射技术.像ssh框架都采用两种技术 xml做配置文件+反射技术. 与反射有关的类包. java.lang.reflect.*;和java.lang.Class; Java中所有类型(包括基本类型)都对应一个Class对象,这个Class就是java.lang.Class.即每一个类型,在Class中都有一个Class对象跟它对应.Class 没有公共构造方法.注意不是没有,是没有公共的. 如何获得Class对象 复制代码 代码如下: .针对每一个对象.getCalss(),

  • JAVA反射机制实例教程

    本文以实例形式详细讲述了Java的反射机制,是Java程序设计中重要的技巧.分享给大家供大家参考.具体分析如下: 首先,Reflection是Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性.例如,使用它能获得 Java 类中各成员的名称并显示出来. Java 的这一能力在实际应用中也许用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性.例如,Pascal.C 或者 C++ 中就没有办法在程序中获得函数

  • 通过java反射机制动态调用某方法的总结(推荐)

    如下: public Object invokeMethod(String className, String methodName, Object[] args) throws Exception{ Class ownerClass = Class.forName(className); Object owner = ownerClass.newInstance(); Class[] argsClass = new Class[args.length]; for (int i = 0, j =

  • Java反射机制及Method.invoke详解

    JAVA反射机制 JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理. 1. 得到某个对象的属性 复制代码 代码如下: public Object get

随机推荐