Java反射学习

    xiaoxiao2022-07-02  110

    Java的反射技术应用广泛,它能够配置:类的权限定名、方法和参数,完成对象的初始化,甚至是反射某些方法。这样就可以大大增强Java的可配置性,Spring IoC的基本原理也是如此,当然Spring IoC的代码要复杂的多。

    Java的发射内容繁多,包括对象的构造、反射方法、注释、参数、接口等。本人最近学习了对象构建和方法的反射调用,主要从这两方面来撰写该文章。在Java中,反射是通过包java.lang.reflect.*实现的。

    一、通过反射构建对象

    (一)无参构造对象

    在Java中允许通过反射配置信息和构建对象,代码如下所示:

    public void sayHello(String name) { System.out.println("Hello Reflect " + name); }

    然后通过反射的方法构造它,代码如下所示:

    public ReflectServiceImpl getInstance() { ReflectServiceImpl reflectServiceImpl = null; try { reflectServiceImpl = (ReflectServiceImpl)Class.forName("com.chenbin.reflect.ReflectServiceImpl") .newInstance(); } catch (Exception e) { e.printStackTrace(); } return reflectServiceImpl; }

    这里的代码就是生成一个对象,然后将其返回。下面这段代码的目的就是给类加载器注册了一个类ReflectServiceImpl的全限定名,然后通过newInstance方法初始化了一个类对象,使用反射的方式也是什么简单。

    reflectServiceImpl = (ReflectServiceImpl)Class.forName("com.chenbin.reflect.ReflectServiceImpl") .newInstance();

    (二)有参构造对象

    以上是没有任何参数的类的反射生成,如果一个类的所有构造方法里都至少存在一个参数,如何用反射构造它。在Java中,只要稍微改变一下就可以了,代码如下所示:

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

    这里实现了含有一个参数的构造方法,这时将不能用之前的办法将其反射生成对象,用一下代码可以完成相同的功能,代码如下所示:

    public ReflectServiceImpl2 getInstance() { ReflectServiceImpl2 reflectServiceImpl2 = null; try { reflectServiceImpl2 = (ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2") .getConstructor(String.class).newInstance("张三"); } catch (Exception e) { e.printStackTrace(); } return reflectServiceImpl2; }

    使用如下代码反射生成对象:

    reflectServiceImpl2 = (ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2") .getConstructor(String.class).newInstance("张三");

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

    反射的优点是只要配置就可以生成对象,可以解除程序的耦合度,比较灵活。反射的缺点是运行比较慢。但是大部分情况下为了灵活,降低程序的耦合度,我们还是会使用反射的,比如Spring IoC容器。

    二、反射方法

    以下主要介绍反射方法,在使用反射方法前要获取方法对象,得到了放大才能够反射,代码如下所示:

    public Object reflectMethod() { Object returnObj = null; ReflectServiceImpl reflectServiceImpl = new ReflectServiceImpl(); try { Method method = ReflectServiceImpl.class.getMethod("sayHello", String.class); returnObj = method.invoke(reflectServiceImpl,"张三"); } catch (Exception e) { e.printStackTrace(); } return returnObj; }

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

    实例:

    通过实例来看看如何反射生成对象和反射调度方法,代码如下所示:

    public Object reflect() { ReflectServiceImpl object = null; try { object = (ReflectServiceImpl)Class.forName("com.chenbin.reflect.ReflectServiceImpl") .newInstance(); Method method = object.getClass().getMethod("sayHello", String.class); method.invoke(object,"张三"); } catch (Exception e) { e.printStackTrace(); } return object; }

    以上就是对反射的学习,希望对看到的大家有所帮助,后续会学习Java设计模式,文章会持续更新哦,记得关注哟!

    最新回复(0)