Java反射技术应用广泛,它能够配置:
- 类的全限定名,方法和参数
- 完成对象的初始化
- 反射某些方法
反射内容有:
- 对象构建
- 反射方法
- 注解
- 参数
- 接口
本文主要针对下面两个方面:
- 对象构建(有参数、没参数)
- 方法的反射
在Java中,反射是通过包java.lang.reflect.*来实现的。
反射的优点是只要配置就可以生成对象,可以降低程序的耦合度,比较灵活。
反射的缺点就是运行比较慢。但是大部分情况下为了灵活性,降低程序的耦合度,我们还是会使用反射的,比如SpringIoC容器。
通过反射构建对象
无参数类
在Java中允许通过反射配置信息构建对象,比如下面的ReflectServiceImpl类:
package com.lean.ssm.chapter2.reflect; /** * Created by mzg on 2017/12/5. */ public class ReflectServiceImpl { public void sayHello(String name){ System.err.println("Hello"+name); } }
通过反射的方法去构建,如下:
//通过反射的方法构建类,无参数 public ReflectServiceImpl getInstance(){ ReflectServiceImpl object = null; try{ object = (ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl" ).newInstance(); }catch (ClassNotFoundException|InstantiationException|IllegalAccessException ex){ ex.printStackTrace(); } return object; }
重点构建语句:
object = (ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl" ).newInstance();
有参数类
有参数类ReflectServiceImpl2:
package com.lean.ssm.chapter2. /** * Created by mzg on 2017/12/5. */ public class ReflectServiceImpl2 { private String name; public ReflectServiceImpl2(String name){ this.name = name; } public void sayHello(){ System.err.println("Hello" + name); } }
实现一个含参数的构建方法:
//通过反射的方法构建类,有参数 public ReflectServiceImpl2 getInstance(){ ReflectServiceImpl2 object = null; try { object = (ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2").getConstructor(String.class).newInstance("张三"); } catch (InstantiationException|IllegalAccessException|InvocationTargetException|NoSuchMethodException|ClassNotFoundException e) { e.printStackTrace(); } return object; }
使用如下代码反射生成对象:
object = (ReflectServiceImpl2)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl2").getConstructor(String.class).newInstance("张三");
过程:
先通过forName加载到类的加载器。然后通过getConstructor方法,它的参数可以是多个,这里定义为String.class,意为有且只有一个参数类型为String的构建参数。通过这个方法可以对重名方法进行排除,此时再用newInstance方法生成对象,只是newInstance方法多了一个参数“张三”而已。实际就等于 object = new ReflectServiceImpl2("张三),只是这里用反射机制来生成这个对象而已。
反射方法
继续以ReflectServiceImpl类为例,代码如下;
/** * 类 : ReflectServiceImpl 反射方法 * @return 方法返回值 */ public Object reflectMethod(){ Object returnObj = null; ReflectServiceImpl target = new ReflectServiceImpl(); Method method = null; try { method = ReflectServiceImpl.class.getMethod("sayHello", String.class); returnObj = method.invoke(target,"张三"); } catch (NoSuchMethodException|IllegalAccessException|InvocationTargetException e) { e.printStackTrace(); } return returnObj; }
对于代码:
method = ReflectServiceImpl.class.getMethod("sayHello", String.class);
当有具体的对象target,而不知道具体是那个类时,也可以使用 target.getClass().getMethod("sayHello",String.class)代替他。
方法 getMethod("sayHello",String.class):
- 第一个参数是方法名称
- 第二个参数是参数类型,是一个列表,多个参数可以继续编写多个类型
方法 returnObj = method.invoke(target,"张三"):
- 第一个参数为target,就是确定那个对象调用方法
- 第二个参数为"张三",等同于 target.sayHello("张三")
- 如果存在多个参数,可以写成Method.invoke(target,obj1,obj2,obj3......)
反射生成对象和反射调度方法的实例,继续以ReflectServiceImpl类为例:
public static Object reflectEx1(){ ReflectServiceImpl object =null; try { object = (ReflectServiceImpl)Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").newInstance(); Method method = object.getClass().getMethod("sayHello", String.class); method.invoke(object,"张三"); } catch (InstantiationException|IllegalAccessException|ClassNotFoundException|NoSuchMethodException|SecurityException| IllegalArgumentException|InvocationTargetException e) { e.printStackTrace(); } return object; }
文章评论