Java 反射机制
【摘要】 反射机制可以帮助我们在动态运行时,获得任意一个类的所有的构造器、方法、变量。很多主流框架都使用了反射技术.像SSH框架就采用了xml做配置文件+反射技术。 为了更好说明反射技术,我们将利用TestObject类来演示:
import java.util.HashMap;
public class TestObject { private String myName;...
反射机制可以帮助我们在动态运行时,获得任意一个类的所有的构造器、方法、变量。很多主流框架都使用了反射技术.像SSH框架就采用了xml做配置文件+反射技术。
为了更好说明反射技术,我们将利用TestObject类来演示:
import java.util.HashMap;
public class TestObject { private String myName; private int myArg; public String hobby; public String schoolName; protected String age; public String[] arr = new String[]{"hello","world"}; public TestObject(){ System.out.println("调用TestObject的无参构造方法"); this.myName = "wongkyunban"; this.myArg = 23; } public TestObject(String name){ System.out.printf("调用TestObject的有一个String型参数的构造方法:%s\n",name); this.myName = name; this.myArg = 21; } private TestObject(int arg){ System.out.printf("调用TestObject的有一个int型参数的构造方法:%d\n",arg); this.myName = "Jack"; this.myArg = arg; } public TestObject(int arg,String name){ System.out.printf("调用TestObject的有两个参数的构造方法"); this.myName = name; this.myArg = arg; } public String getMyName() { return myName; } public void setMyName(String myName) { this.myName = myName; } public int getMyArg() { return myArg; } public void setMyArg(int myArg) { this.myArg = myArg; } private void con(){ System.out.printf("hello,%s\n","您调用了一个私有方法"); } public void printHobby(){ System.out.printf("Hobby:%s\n",hobby); } protected void byebye(){ System.out.printf("Bye bye!\n"); } public void handleData(String arg1 ,HashMap<Integer,String> map){ System.out.printf("%s--->%s\n",arg1,map.get("name")); } private void say(String name){ System.out.printf("hello,%s\n",name); }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
使用反射技术获得所有构造方法(包括私有的,非私有的)
默认权限的指的是没有修饰符修饰的。
方法 | 描述 |
---|---|
public Constructor getConstructor(Class… parameterTypes) | 获得指定的具有public访问权限的构造方法 |
public Constructor[] getConstructors() | 获得所有的具有public访问权限的构造方法 |
public Constructor getDeclaredConstructor(Class… parameterTypes) | 获得指定的构造方法,不管它的访问权限是什么。 |
public Constructor[] getDeclaredConstructors() | 获得所有的构造方法,包括public, private,protected和默认权限的 |
。
示例代码:
//获取构造函数 private void getConstructor(){ try { Class<?> clazz = Class.forName("TestObject"); //获得所有的具有public访问权限的构造方法 Constructor<?>[] constructors = clazz.getConstructors(); System.out.printf("所有的具有public访问权限的构造方法:\n"); for(Constructor o:constructors){ System.out.printf("%s\n",o.toString()); } //获得指定的具有public访问权限的构造方法 Constructor<?> constructor = clazz.getConstructor(String.class); System.out.printf("获得指定的具有public访问权限的构造方法:\n"); System.out.printf("%s\n",constructor.toString()); //获得所有的构造方法,包括public, private,protected和默认权限的 Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors(); System.out.printf("获得所有的构造方法,包括public, private,protected和默认权限的:\n"); for(Object o:declaredConstructors){ System.out.printf("%s\n",o.toString()); } //获得指定的构造方法,不管它的访问权限是什么 Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(int.class); System.out.printf("获得指定的构造方法,不管它的访问权限是什么:\n"); System.out.printf("%s\n",declaredConstructor.toString()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
使用获得的构造方法(包括私有的,非私有的)实例化对象。
注意事项: 如果该方法,或者该变量不是 public 访问权限的,我们应该调用相应的 setAccessible(true) 方法,才能访问得到。
//使用获得的构造函数,构造对象 public void useConstructor(){ try { Class<?> clazz = Class.forName("TestObject"); Constructor constructor = clazz.getConstructor(String.class); Object o = constructor.newInstance("Hello"); TestObject testObject = (TestObject) o; testObject.byebye(); Constructor privateConstructor = clazz.getDeclaredConstructor(int.class); //privateConstructor的访问权限不是public所以一定要执行下面这条语句 privateConstructor.setAccessible(true); Object o1 = privateConstructor.newInstance(88); TestObject testObject1 = (TestObject)o1; testObject1.byebye(); }catch (Exception e){ e.printStackTrace(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
使用反射获得所有的 Filed 变量
方法 | 描述 |
---|---|
public Field[] getFields() | 获得所有的具有public访问权限的字段 |
public Field getField(String name) | 获得指定的具有public访问权限的字段 |
public Field[] getDeclaredFields() | 获得所有字段,包括public, private,protected和默认权限的字段 |
public Field getDeclaredField(String name) | 获得指定的字段,字段的访问权限包括public, private,protected和默认权限的 |
示例代码:
//获取所有字段 public void getMyField(){ try { Class<?> clazz = Class.forName("TestObject"); //获得所有的具有public访问权限的字段 Field[] fields = clazz.getFields(); System.out.printf("获得所有的具有public访问权限的字段:\n"); for(Field o:fields){ System.out.printf("%s\n",o.toString()); } //获得指定的具有public访问权限的字段 System.out.printf("获得指定的具有public访问权限的字段:\n"); Field field = clazz.getField("hobby"); System.out.printf("%s\n",field.toString()); //获得所有字段,包括public, private,protected和默认权限的字段 Field[] declaredfields = clazz.getDeclaredFields(); System.out.printf("获得所有的字段,包括public, private,protected和默认权限的字段:\n"); for(Field o:declaredfields){ System.out.printf("%s\n",o.toString()); } //获得指定的字段,字段的访问权限包括public, private,protected和默认权限的 System.out.printf("获得指定的字段,字段的访问权限包括public, private,protected和默认权限的:\n"); Field declaredField = clazz.getDeclaredField("myName"); System.out.printf("%s\n",declaredField.toString()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
使用获得的字段
注意:如果该方法,或者该变量不是 public 访问权限的,我们应该调用相应的 setAccessible(true) 方法,才能访问得到
//使用获得的字段 public void useMyfield(){ try { Class<?> clazz = Class.forName("TestObject"); Field field = clazz.getField("hobby");//有public权限的 TestObject object = new TestObject(); System.out.printf("%s\n",(String)field.get(object)); field.set(object,"PingPong"); System.out.printf("%s\n",(String)field.get(object)); Field privateField = clazz.getDeclaredField("myName"); privateField.setAccessible(true);//对于访问权限不是public的字段,要想访问,必须调用setAccessible。 System.out.printf("%s\n",(String)privateField.get(object)); privateField.set(object,"Wong"); System.out.printf("%s\n",(String)privateField.get(object)); }catch (Exception e){ e.printStackTrace(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
使用反射获取所有的 Method
方法 | 描述 |
---|---|
public Method[] getMethods() | 获得所有的具有public访问权限的方法 |
public Method getMethod(String name, Class<?>… parameterTypes) | 获得指定的具有public访问权限的方法 |
public Method[] getDeclaredMethods() | 获得所有方法,包括public, private,protected和默认权限的方法 |
public Method getDeclaredMethod(String name, Class<?>… parameterTypes) | 获得指定的方法,方法的访问权限包括public, private,protected和默认权限的 |
示例代码:
//获取所有方法 public void getAllMethod(){ try { Class<?> clazz = Class.forName("TestObject"); //获得所有的具有public访问权限的方法 Method[] methods = clazz.getMethods(); System.out.printf("获得所有的具有public访问权限的方法:\n "); for(Object o:methods){ System.out.printf("%s\n",o.toString()); } //获得指定的具有public访问权限的方法 Method method = clazz.getMethod("setMyArg", int.class); System.out.printf("获得指定的具有public访问权限的方法:\n "); System.out.printf("%s\n",method.toString()); //获得所有方法,包括public, private,protected和默认权限的方法 Method[] declaredMethods = clazz.getDeclaredMethods(); System.out.printf("获得所有方法,包括public, private,protected和默认权限的方法:\n"); for(Object o:declaredMethods){ System.out.printf("%s\n",o.toString()); } //获得指定的方法,方法的访问权限包括public, private,protected和默认权限的 Method declaredMethod = clazz.getDeclaredMethod("say", String.class); System.out.printf("获得指定的方法,方法的访问权限包括public, private,protected和默认权限的:\n"); System.out.printf("%s\n",declaredMethod.toString()); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
使用已获得的方法
注意事项: 如果该方法,或者该变量不是 public 访问权限的,我们应该调用相应的 setAccessible(true) 方法,才能访问得到。如果不用就会报如下错:
java.lang.IllegalAccessException: Class Main can not access a member of class TestObject with modifiers "private"
- 1
//使用已获得的方法 public void useMethod(){ try { Class<?> clazz = Class.forName("TestObject"); Method method = clazz.getMethod("handleData", String.class, HashMap.class);//有public权限的 TestObject testObject = new TestObject(); HashMap<String, String> hashMap = new HashMap<>(); hashMap.put("name", "Kingkong"); method.invoke(testObject, "Tom", hashMap); Method privateMethod = clazz.getDeclaredMethod("con"); privateMethod.setAccessible(true);//对于访问权限不是public的方法,要想访问,必须调用setAccessible。 privateMethod.invoke(testObject); }catch (Exception e){ e.printStackTrace(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
使用反射操作数组
//利用反射技术处理数组 public void handlArray() { String[] nameArr = new String[]{"Tom", "John", "Lucy", "Barkerly"}; Array.set(nameArr, 0, "Wongkyunban"); //修改数组的值 Class clazz = nameArr.getClass(); if (clazz.isArray()) { int len = Array.getLength(nameArr); for (int i = 0; i < len; i++) { Object object = Array.get(nameArr, i); String className = object.getClass().getName(); System.out.println("--> object=" + object + ",className=" + className); } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
使用反射获得泛型类型
//使用反射获得泛型类型 public void getGenericType(){ try { //Class<?> clazz = TestObject.class;与下面等价 Class<?> clazz = Class.forName("TestObject"); Method genericTypeMethod = clazz.getDeclaredMethod("handleData", String.class,HashMap.class); //获得所有的参数类型 Type[] genericParameterTypes = genericTypeMethod.getGenericParameterTypes(); //检验是否为空 if (null == genericParameterTypes || genericParameterTypes.length < 1) { return; } //取方法第2个参数,获得泛型参数的类型 ParameterizedType parameterizedType = (ParameterizedType)genericParameterTypes[1]; Type rawType = parameterizedType.getRawType(); System.out.printf("--->raw type:%s\n",rawType); //取得第二个泛型参数类型 Type[] actualTypeArgs = parameterizedType.getActualTypeArguments(); if(actualTypeArgs == genericParameterTypes || actualTypeArgs.length < 1){ return; } //打印出每一个类型 for (int i = 0; i < actualTypeArgs.length; i++){ Type type = actualTypeArgs[i]; System.out.printf("--->Type:%s\n",type); } }catch (Exception e){ e.printStackTrace(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
获得 Metho,Field,Constructor 的访问权限 ( public,private,ptotected 等)
//获得Metho,Field,Constructor 的访问权限 public void showPermmit(){ try { Class<?> clazz = Class.forName("TestObject"); Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor constructor:constructors){ int modifier = constructor.getModifiers(); System.out.printf("构造器%s,权限是%s\n",constructor.toString(), Modifier.toString(modifier)); } System.out.printf("\n\n"); Field[] fields = clazz.getDeclaredFields(); for (Field field:fields){ int modifier = field.getModifiers(); System.out.printf("字段%s,权限是%s\n",field.toString(), Modifier.toString(modifier)); } System.out.printf("\n\n"); Method[] methods = clazz.getDeclaredMethods(); for (Method method:methods){ int modifier = method.getModifiers(); System.out.printf("方法%s,权限是%s\n",method.toString(), Modifier.toString(modifier)); } }catch (Exception e){ e.printStackTrace(); } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
文章来源: blog.csdn.net,作者:WongKyunban,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/weixin_40763897/article/details/89139489
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)