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 }
效果图: