反射

2018-07-20 05:49:57来源:博客园 阅读 ()

新老客户大回馈,云服务器低至5折

一、定义

  JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

二、使用

  1、反射Java类

    反射的类(People类)

 1 package reverse;
 2 
 3 public class People {
 4 
 5     Integer id;
 6     public String name;
 7     private String phone;
 8     protected String email;
 9 
10     People() {
11         System.out.println("调用默认的构造方法");
12     }
13 
14     public People(Integer id) {
15         System.out.println("调用public修饰的构造方法:" + "people [id=" + id + "]");
16     }
17 
18     public People(Integer id, String name) {
19         System.out.println("调用public修饰的构造方法:" + "people [id=" + id + ", name=" + name + "]");
20     }
21 
22     private People(String name, String phone, String email) {
23         System.out
24                 .println("调用private修饰的构造方法:" + "people [name=" + name + ", phone=" + phone + ", email=" + email + "]");
25     }
26 
27     protected People(Integer id, String name, String phone, String email) {
28         System.out.println("调用protected修饰的构造方法:" + "people [id=" + id + ", name=" + name + ", phone=" + phone
29                 + ", email=" + email + "]");
30     }
31 
32     @Override
33     public String toString() {
34         return "People [id=" + id + ", name=" + name + ", phone=" + phone + ", email=" + email + "]";
35     }
36 
37     void show1() {
38         System.out.println("调用默认的方法");
39     }
40 
41     private void show2(Integer temp) {
42         System.out.println("调用private修饰的方法,参数temp值为" + temp);
43     }
44 
45     protected void show3() {
46         System.out.println("调用protected修饰的方法");
47     }
48 
49     public void show4(Integer temp) {
50         System.out.println("调用public修饰的方法,参数temp值为" + temp);
51     }
52 
53     public String show5(Integer temp1, String temp2) {
54         System.out.println("调用public修饰的方法,参数temp1值为" + temp1 + ",参数temp2值为" + temp2);
55         return temp1 + temp2;
56     }
57 
58 }

    测试反射的类(testPeople类)

  1 package reverse;
  2 
  3 import java.lang.reflect.Constructor;
  4 import java.lang.reflect.Field;
  5 import java.lang.reflect.InvocationTargetException;
  6 import java.lang.reflect.Method;
  7 
  8 /**
  9  * 反射(通过class类的静态方法forName()获取类)
 10  * 
 11  * @author WJY
 12  *
 13  */
 14 public class testPeople {
 15 
 16     public static void main(String[] args) {
 17 
 18         Class<?> clazz = null;
 19 
 20         try {
 21             clazz = Class.forName("reverse.People");
 22         } catch (ClassNotFoundException e) {
 23             System.out.println("类找不到异常");
 24         }
 25 
 26         try {
 27             constructors(clazz);
 28         } catch (NoSuchMethodException e1) {
 29             e1.printStackTrace();
 30         } catch (SecurityException e1) {
 31             e1.printStackTrace();
 32         } catch (InstantiationException e1) {
 33             e1.printStackTrace();
 34         } catch (IllegalAccessException e1) {
 35             e1.printStackTrace();
 36         } catch (IllegalArgumentException e1) {
 37             e1.printStackTrace();
 38         } catch (InvocationTargetException e1) {
 39             e1.printStackTrace();
 40         }
 41 
 42         try {
 43             field(clazz);
 44         } catch (NoSuchFieldException e) {
 45             e.printStackTrace();
 46         } catch (SecurityException e) {
 47             e.printStackTrace();
 48         } catch (NoSuchMethodException e) {
 49             e.printStackTrace();
 50         } catch (InstantiationException e) {
 51             e.printStackTrace();
 52         } catch (IllegalAccessException e) {
 53             e.printStackTrace();
 54         } catch (IllegalArgumentException e) {
 55             e.printStackTrace();
 56         } catch (InvocationTargetException e) {
 57             e.printStackTrace();
 58         }
 59 
 60         try {
 61             method(clazz);
 62         } catch (NoSuchMethodException e) {
 63             e.printStackTrace();
 64         } catch (SecurityException e) {
 65             e.printStackTrace();
 66         } catch (InstantiationException e) {
 67             e.printStackTrace();
 68         } catch (IllegalAccessException e) {
 69             e.printStackTrace();
 70         } catch (IllegalArgumentException e) {
 71             e.printStackTrace();
 72         } catch (InvocationTargetException e) {
 73             e.printStackTrace();
 74         }
 75 
 76     }
 77 
 78     /**
 79      * 获取构造方法
 80      * 
 81      * @param clazz
 82      * @throws NoSuchMethodException
 83      * @throws SecurityException
 84      * @throws InstantiationException
 85      * @throws IllegalAccessException
 86      * @throws IllegalArgumentException
 87      * @throws InvocationTargetException
 88      */
 89     private static void constructors(Class<?> clazz) throws NoSuchMethodException, SecurityException,
 90             InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 91 
 92         Constructor<?>[] constructors = clazz.getConstructors();// 获取public修饰的构造方法
 93 
 94         System.out.println("public修饰的构造方法:");
 95         for (Constructor<?> constructor : constructors) {
 96             System.out.println(constructor);
 97         }
 98 
 99         Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();// 获取所有构造方法
100 
101         System.out.println("所有构造方法:");
102         for (Constructor<?> declaredConstructor : declaredConstructors) {
103             System.out.println(declaredConstructor);
104         }
105 
106         System.out.println("==========华丽的分割线==========");
107 
108         Constructor<?> constructor1 = clazz.getConstructor(Integer.class);// 获取指定的public修饰的构造方法:根据构造方法的参数类型获取,参数类型顺序需要一致
109         Constructor<?> constructor2 = clazz.getConstructor(Integer.class, String.class);// 获取指定的public修饰的构造方法:根据构造方法的参数类型获取,参数类型顺序需要一致
110 
111         System.out.println("获取指定的public修饰的构造方法,参数为(Integer):" + constructor1);
112         System.out.println("获取指定的public修饰的构造方法,参数为(Integer, String):" + constructor2);
113 
114         Constructor<?> declaredConstructor1 = clazz.getDeclaredConstructor();// 获取指定的构造方法:根据构造方法的参数类型获取,参数类型顺序需要一致,无参为获取空构造
115         Constructor<?> declaredConstructor2 = clazz.getDeclaredConstructor(Integer.class);// 获取指定的构造方法:根据构造方法的参数类型获取,参数类型顺序需要一致
116         Constructor<?> declaredConstructor3 = clazz.getDeclaredConstructor(Integer.class, String.class);// 获取指定的构造方法:根据构造方法的参数类型获取,参数类型顺序需要一致
117         Constructor<?> declaredConstructor4 = clazz.getDeclaredConstructor(String.class, String.class, String.class);// 获取指定的构造方法:根据构造方法的参数类型获取,参数类型顺序需要一致
118         Constructor<?> declaredConstructor5 = clazz.getDeclaredConstructor(Integer.class, String.class, String.class,
119                 String.class);// 获取指定的构造方法:根据构造方法的参数类型获取,参数类型顺序需要一致
120 
121         System.out.println("获取指定的构造方法,参数为():" + declaredConstructor1);
122         System.out.println("获取指定的构造方法,参数为(Integer):" + declaredConstructor2);
123         System.out.println("获取指定的构造方法,参数为(Integer, String):" + declaredConstructor3);
124         System.out.println("获取指定的构造方法,参数为(String, String, String):" + declaredConstructor4);
125         System.out.println("获取指定的构造方法,参数为(Integer, String, String, String):" + declaredConstructor5);
126 
127         declaredConstructor4.setAccessible(true);// 暴力访问,即忽略掉修饰符
128         declaredConstructor4.newInstance("特工", "这也不知道", "那也不知道");// 调用该方法
129 
130         declaredConstructor5.newInstance(007, "特工", "这也不知道", "那也不知道");// 调用该方法
131 
132     }
133 
134     /**
135      * 获取属性
136      * 
137      * @param clazz
138      * @throws NoSuchFieldException
139      * @throws SecurityException
140      * @throws NoSuchMethodException
141      * @throws InstantiationException
142      * @throws IllegalAccessException
143      * @throws IllegalArgumentException
144      * @throws InvocationTargetException
145      */
146     private static void field(Class<?> clazz) throws NoSuchFieldException, SecurityException, NoSuchMethodException,
147             InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
148 
149         Field[] fields = clazz.getFields();// 获取public修饰的属性
150 
151         System.out.println("public修饰的属性:");
152         for (Field field : fields) {
153             System.out.println(field);
154         }
155 
156         Field[] declaredFields = clazz.getDeclaredFields();// 获取所有属性
157 
158         System.out.println("所有属性:");
159         for (Field field : declaredFields) {
160             System.out.println(field);
161         }
162 
163         System.out.println("==========华丽的分割线==========");
164 
165         Field field = clazz.getField("name");// 获取指定的public修饰的属性:根据属性的参数类型获取
166 
167         System.out.println("获取指定的public修饰的属性,参数为(Integer):" + field);
168 
169         Field declaredField1 = clazz.getDeclaredField("id");// 获取指定的属性:根据属性的参数类型获取
170         Field declaredField2 = clazz.getDeclaredField("name");// 获取指定的属性:根据属性的参数类型获取
171         Field declaredField3 = clazz.getDeclaredField("phone");// 获取指定的属性:根据属性的参数类型获取
172         Field declaredField4 = clazz.getDeclaredField("email");// 获取指定的属性:根据属性的参数类型获取
173 
174         System.out.println("获取指定的属性,属性名为(id):" + declaredField1);
175         System.out.println("获取指定的属性,属性名为(name):" + declaredField2);
176         System.out.println("获取指定的属性,属性名为(phone):" + declaredField3);
177         System.out.println("获取指定的属性,属性名为(email):" + declaredField4);
178 
179         Constructor<?> constructor = clazz.getDeclaredConstructor();// 获取空构造
180 
181         Object object = constructor.newInstance();// 调用空构造
182 
183         declaredField3.setAccessible(true);// 暴力访问,即忽略掉修饰符
184 
185         declaredField1.set(object, 007);
186         declaredField2.set(object, "特工");
187         declaredField3.set(object, "这也不知道");
188         declaredField4.set(object, "那也不知道");// 属性赋值
189 
190         People people = (People) object;// 将Object对象强转为People对象
191 
192         System.out.println("获取所有属性的值:" + people.toString());// 调用重写的toString()方法输出所有属性名和属性值
193 
194     }
195 
196     /**
197      * 获取方法
198      * 
199      * @param clazz
200      * @throws NoSuchMethodException
201      * @throws SecurityException
202      * @throws InstantiationException
203      * @throws IllegalAccessException
204      * @throws IllegalArgumentException
205      * @throws InvocationTargetException
206      */
207     private static void method(Class<?> clazz) throws NoSuchMethodException, SecurityException, InstantiationException,
208             IllegalAccessException, IllegalArgumentException, InvocationTargetException {
209 
210         Method[] methods = clazz.getMethods();// 获取public修饰的方法
211 
212         System.out.println("public修饰的方法:");
213         for (Method method : methods) {
214             System.out.println(method);
215         }
216 
217         Method[] declaredMethods = clazz.getDeclaredMethods();// 获取所有方法
218 
219         System.out.println("所有方法:");
220         for (Method method : declaredMethods) {
221             System.out.println(method);
222         }
223 
224         System.out.println("==========华丽的分割线==========");
225 
226         Method method1 = clazz.getMethod("show4", Integer.class);// 获取指定的public修饰的方法:根据方法名和参数类型获取,参数类型顺序需要一致
227         Method method2 = clazz.getMethod("show5", Integer.class, String.class);// 获取指定的public修饰的方法:根据方法名和参数类型获取,参数类型顺序需要一致
228 
229         System.out.println("获取指定的public修饰的方法,参数为(Integer):" + method1);
230         System.out.println("获取指定的public修饰的方法,参数为(Integer, String):" + method2);
231 
232         Method declaredMethod1 = clazz.getDeclaredMethod("show1");// 获取指定的方法:根据方法名和参数类型获取,参数类型顺序需要一致
233         Method declaredMethod2 = clazz.getDeclaredMethod("show2", Integer.class);// 获取指定的方法:根据方法名和参数类型获取,参数类型顺序需要一致
234         Method declaredMethod3 = clazz.getDeclaredMethod("show3");// 获取指定的方法:根据方法名和参数类型获取,参数类型顺序需要一致
235         Method declaredMethod4 = clazz.getDeclaredMethod("show4", Integer.class);// 获取指定的方法:根据方法名和参数类型获取,参数类型顺序需要一致
236         Method declaredMethod5 = clazz.getDeclaredMethod("show5", Integer.class, String.class);// 获取指定的方法:根据方法名和参数类型获取,参数类型顺序需要一致
237 
238         System.out.println("获取指定的方法,方法名为(show1):" + declaredMethod1);
239         System.out.println("获取指定的方法,方法名为(show2),参数为(Integer):" + declaredMethod2);
240         System.out.println("获取指定的方法,方法名为(show3):" + declaredMethod3);
241         System.out.println("获取指定的方法,方法名为(show4),参数为(Integer):" + declaredMethod4);
242         System.out.println("获取指定的方法,方法名为(show5),参数为(Integer, String):" + declaredMethod5);
243 
244         Constructor<?> constructor = clazz.getDeclaredConstructor();
245 
246         Object object = constructor.newInstance();
247 
248         declaredMethod4.invoke(object, 100);
249 
250         String result = (String) declaredMethod5.invoke(object, 100, "元");// 设置参数并获得方法的返回值
251         System.out.println("方法返回值:" + result);
252 
253         declaredMethod2.setAccessible(true);
254         declaredMethod2.invoke(object, 200);
255 
256     }
257 
258 }

    测试结果

 1 public修饰的构造方法:
 2 public reverse.People(java.lang.Integer,java.lang.String)
 3 public reverse.People(java.lang.Integer)
 4 所有构造方法:
 5 protected reverse.People(java.lang.Integer,java.lang.String,java.lang.String,java.lang.String)
 6 private reverse.People(java.lang.String,java.lang.String,java.lang.String)
 7 public reverse.People(java.lang.Integer,java.lang.String)
 8 public reverse.People(java.lang.Integer)
 9 reverse.People()
10 ==========华丽的分割线==========
11 获取指定的public修饰的构造方法,参数为(Integer):public reverse.People(java.lang.Integer)
12 获取指定的public修饰的构造方法,参数为(Integer, String):public reverse.People(java.lang.Integer,java.lang.String)
13 获取指定的构造方法,参数为():reverse.People()
14 获取指定的构造方法,参数为(Integer):public reverse.People(java.lang.Integer)
15 获取指定的构造方法,参数为(Integer, String):public reverse.People(java.lang.Integer,java.lang.String)
16 获取指定的构造方法,参数为(String, String, String):private reverse.People(java.lang.String,java.lang.String,java.lang.String)
17 获取指定的构造方法,参数为(Integer, String, String, String):protected reverse.People(java.lang.Integer,java.lang.String,java.lang.String,java.lang.String)
18 调用private修饰的构造方法:people [name=特工, phone=这也不知道, email=那也不知道]
19 调用protected修饰的构造方法:people [id=7, name=特工, phone=这也不知道, email=那也不知道]
20 public修饰的属性:
21 public java.lang.String reverse.People.name
22 所有属性:
23 java.lang.Integer reverse.People.id
24 public java.lang.String reverse.People.name
25 private java.lang.String reverse.People.phone
26 protected java.lang.String reverse.People.email
27 ==========华丽的分割线==========
28 获取指定的public修饰的属性,参数为(Integer):public java.lang.String reverse.People.name
29 获取指定的属性,属性名为(id):java.lang.Integer reverse.People.id
30 获取指定的属性,属性名为(name):public java.lang.String reverse.People.name
31 获取指定的属性,属性名为(phone):private java.lang.String reverse.People.phone
32 获取指定的属性,属性名为(email):protected java.lang.String reverse.People.email
33 调用默认的构造方法
34 获取所有属性的值:People [id=7, name=特工, phone=这也不知道, email=那也不知道]
35 public修饰的方法:
36 public java.lang.String reverse.People.toString()
37 public void reverse.People.show4(java.lang.Integer)
38 public java.lang.String reverse.People.show5(java.lang.Integer,java.lang.String)
39 public final void java.lang.Object.wait() throws java.lang.InterruptedException
40 public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
41 public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
42 public boolean java.lang.Object.equals(java.lang.Object)
43 public native int java.lang.Object.hashCode()
44 public final native java.lang.Class java.lang.Object.getClass()
45 public final native void java.lang.Object.notify()
46 public final native void java.lang.Object.notifyAll()
47 所有方法:
48 public java.lang.String reverse.People.toString()
49 public void reverse.People.show4(java.lang.Integer)
50 public java.lang.String reverse.People.show5(java.lang.Integer,java.lang.String)
51 void reverse.People.show1()
52 private void reverse.People.show2(java.lang.Integer)
53 protected void reverse.People.show3()
54 ==========华丽的分割线==========
55 获取指定的public修饰的方法,参数为(Integer):public void reverse.People.show4(java.lang.Integer)
56 获取指定的public修饰的方法,参数为(Integer, String):public java.lang.String reverse.People.show5(java.lang.Integer,java.lang.String)
57 获取指定的方法,方法名为(show1):void reverse.People.show1()
58 获取指定的方法,方法名为(show2),参数为(Integer):private void reverse.People.show2(java.lang.Integer)
59 获取指定的方法,方法名为(show3):protected void reverse.People.show3()
60 获取指定的方法,方法名为(show4),参数为(Integer):public void reverse.People.show4(java.lang.Integer)
61 获取指定的方法,方法名为(show5),参数为(Integer, String):public java.lang.String reverse.People.show5(java.lang.Integer,java.lang.String)
62 调用默认的构造方法
63 调用public修饰的方法,参数temp值为100
64 调用public修饰的方法,参数temp1值为100,参数temp2值为元
65 方法返回值:100元
66 调用private修饰的方法,参数temp值为200

    反射的类(Main类)

 1 package reverse;
 2 
 3 public class Main {
 4 
 5     public static void main(String[] args) {
 6 
 7         System.out.println("main方法正在运行");
 8 
 9     }
10 
11 }

    测试反射的类(testMain类)

 1 package reverse;
 2 
 3 import java.lang.reflect.InvocationTargetException;
 4 import java.lang.reflect.Method;
 5 
 6 /**
 7  * 反射(通过class类的静态方法forName()获取类)
 8  * 
 9  * @author WJY
10  *
11  */
12 public class testMain {
13 
14     public static void main(String[] args) {
15 
16         try {
17 
18             Class<?> clazz = Class.forName("reverse.Main");
19             Method method = clazz.getMethod("main", String[].class);
20             method.invoke(null, (Object) new String[] {});// 调用main方法
21 
22         } catch (ClassNotFoundException e) {
23             e.printStackTrace();
24         } catch (NoSuchMethodException e) {
25             e.printStackTrace();
26         } catch (SecurityException e) {
27             e.printStackTrace();
28         } catch (IllegalAccessException e) {
29             e.printStackTrace();
30         } catch (IllegalArgumentException e) {
31             e.printStackTrace();
32         } catch (InvocationTargetException e) {
33             e.printStackTrace();
34         }
35 
36     }
37 
38 }

    测试结果

main方法正在运行

  2、反射配置文件

    反射的配置文件(pro.properties)

className=reverse.Main
methodName=main

    测试反射的类(testProperties)

 1 package reverse;
 2 
 3 import java.io.File;
 4 import java.io.FileNotFoundException;
 5 import java.io.FileReader;
 6 import java.io.IOException;
 7 import java.io.Reader;
 8 import java.lang.reflect.InvocationTargetException;
 9 import java.lang.reflect.Method;
10 import java.util.Properties;
11 
12 public class testProperties {
13 
14     public static void main(String[] args) {
15 
16         Reader r = null;
17 
18         try {
19 
20             r = new FileReader(new File("D:\\Java Workspace\\test\\src\\reverse\\pro.properties"));
21 
22             Properties properties = new Properties();// 获取配置文件的对象
23             properties.load(r);// 加载配置文件
24 
25             String className = properties.getProperty("className");
26             String methodName = properties.getProperty("methodName");// 根据key获取对应value
27 
28             System.out.println("className:" + className);
29             System.out.println("methodName:" + methodName);
30 
31             Class<?> clazz = Class.forName(className);
32             Method method = clazz.getMethod(methodName, String[].class);
33             method.invoke(null, (Object) new String[] {});// 调用main方法
34 
35         } catch (FileNotFoundException e) {
36             e.printStackTrace();
37         } catch (IOException e) {
38             e.printStackTrace();
39         } catch (ClassNotFoundException e) {
40             e.printStackTrace();
41         } catch (NoSuchMethodException e) {
42             e.printStackTrace();
43         } catch (SecurityException e) {
44             e.printStackTrace();
45         } catch (IllegalAccessException e) {
46             e.printStackTrace();
47         } catch (IllegalArgumentException e) {
48             e.printStackTrace();
49         } catch (InvocationTargetException e) {
50             e.printStackTrace();
51         } finally {
52 
53             try {
54                 r.close();
55             } catch (IOException e) {
56                 e.printStackTrace();
57             }
58 
59         }
60 
61     }
62 
63 }

    测试结果

className:reverse.Main
methodName:main
main方法正在运行

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:千里之行,始于足下

下一篇:java Spring 之IOC依赖注入