Java反射机制(三):调用对象的私有属性和方法
来源:互联网 发布:apache源码 编辑:程序博客网 时间:2024/06/06 08:13
一、 通过反射调用类中的方法
在正常情况下,得到类的对象后,我们就可以直接调用类中的方法了,如果要想调用的话,则肯定必须清楚地知道要调用的方法是什么,之后通过Class类中的getMethod方法,可得到Method对象。
public Method getMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
当获取到Method对象后,可以通过该对象来执行方法,但是在方法调用的时候,因为会牵扯到方法中参数的问题,所以通过getMethod()取得的时候,必须设置好参数类型。package org.chen.yuan.reflect;interface China{// 定义China接口public static final String NATIONAL = "China" ;// 定义全局常量public static final String AUTHOR = "李兴华" ;// 定义全局常量public void sayChina() ;// 无参的,没有返回值的方法public String sayHello(String name,int age) ;// 定义有两个参数的方法,并返回内容}public class Person implements China{private String name ;private int age ;public Person(){// 无参构造}public Person(String name){this.name = name ;// 设置name属性}public Person(String name,int age){this(name) ;this.age = age ;}public void sayChina(){// 覆写方法System.out.println("作者:" + AUTHOR + ",国籍:" + NATIONAL) ;}public String sayHello(String name,int age){return name + ",你好!我今年:" + age + "岁了!" ;}public void setName(String name){this.name = name ;}public void setAge(int age){this.age = age ;}public String getName(){return this.name ;}public int getAge(){return this.age ;}};我们调用sayChina()方法,此方法中没有任何参数。
执行调用的方法,需通过Method的invoke方法来实现:
public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
示例1:(调用无参的方法)
package org.chen.yuan.reflect;interface China{// 定义China接口public static final String NATIONAL = "China" ;// 定义全局常量public static final String AUTHOR = "沉缘" ;// 定义全局常量public void sayChina() ;// 无参的,没有返回值的方法public String sayHello(String name,int age) ;// 定义有两个参数的方法,并返回内容}public class Person implements China{private String name ;private int age ;public Person(){// 无参构造}public Person(String name){this.name = name ;// 设置name属性}public Person(String name,int age){this(name) ;this.age = age ;}public void sayChina(){// 覆写方法System.out.println("作者:" + AUTHOR + ",国籍:" + NATIONAL) ;}public String sayHello(String name,int age){return name + ",你好!我今年:" + age + "岁了!" ;}public void setName(String name){this.name = name ;}public void setAge(int age){this.age = age ;}public String getName(){return this.name ;}public int getAge(){return this.age ;}};
我们在Person.java 类中定义了一个无参方法sayChina和一个有参数的方法sayHello,接下来,我们调用无参数的方法:
package org.chen.yuan.reflect;import java.lang.reflect.Method;public class InvokeSyaChinaDemo{ public static void main(String[] args) { Class<?> c1 = null; try { c1 = Class.forName("org.chen.yuan.reflect.Person"); Method met = c1.getMethod("sayChina"); met.invoke(c1.newInstance()); } catch (Exception e) { e.printStackTrace(); } }}
输出: 作者:沉缘,国籍:China
可以看出,通过上述反射的方式,我们能够顺利的调用Person类中的方法。 那思考下,如果我们要调用含有参数的方法sayHello,该如何做呢?
可以想象,如果方法里存在了参数,则必须设置参数的类型及内容。
public class InvokeSayHelloDemo{ public static void main(String[] args) throws Exception { Class<?> c1 = null; c1 = Class.forName("org.chen.yuan.reflect.Person"); Method met = c1.getMethod("sayHello", String.class, int.class); String result = (String) met.invoke(c1.newInstance(), "沉缘", 25); System.out.println(result); }}
输出: 沉缘,你好!我今年:25岁了!
二、 通过反射调用类中的setter及getter方法
setter和getter方法是访问类属性的标准方法,如果一个类中的属性被封装,则必须通过setter及getter方法设设置和取得,实际上此方法的操作之所以要这样规定,主要是由于反射机制可以给予支持。
通过反射可以调用setter及getter方法。
package org.chen.yuan.reflect;import java.lang.reflect.Method;public class InvokeSetGetDemo{ public static void main(String[] args) throws Exception { Class<?> c1 = null; Object obj = null; c1 = Class.forName("org.chen.yuan.reflect.Person"); obj = c1.newInstance(); setter(obj, "name", "沉缘", String.class); getter(obj, "name"); setter(obj, "age", 25, int.class); getter(obj, "age"); } /** * @param obj 要操作的对象 * @param att 要操作的属性 * @param value 要设置的属性数据 * @param type 要设置的属性的类型 */ public static void setter(Object obj, String att, Object value, Class<?> type) { try { Method met = obj.getClass().getMethod("set" + initStr(att), type); met.invoke(obj, value); } catch (Exception e) { e.printStackTrace(); } } /** * @param obj 要操作的对象 * @param att 要操作的属性 */ public static void getter(Object obj, String att) throws Exception { Method met = obj.getClass().getMethod("get" + initStr(att)); System.out.println(met.invoke(obj)); } /** * 将单词首字母大写 * * @param old * @return */ public static String initStr(String old) { String newStr = old.substring(0, 1).toUpperCase() + old.substring(1); return newStr; }}
三、 通过反射调用属性
如果假设要操作一个类中的属性,则也可以通过Field完成,而不必麻烦的通过setter和getter。Class类中,获取类中Field的方法:
1) 得到类中公共属性
public Field getField(String name) throws NoSuchFieldException, SecurityException
2)得到本类属性public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException
而在Field类中,提供了获取属性内容及设置属性内容的方法:
1) 获取属性内容
public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException
2) 设置属性内容public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException
还有一点需要注意,访问类中的私有属性时,必须要让该属性对外可见:
public void setAccessible(boolean flag) throws SecurityException
该方法继承自Field的父类:Class AccessibleObject
只要把该方法的参数内容设置为true即可。
public class InvokeFieldDemo{ public static void main(String args[]) throws Exception { Class<?> c1 = null; Object obj = null; c1 = Class.forName("org.chen.yuan.reflect.Person"); // 实例化Class对象 obj = c1.newInstance(); Field nameField = null; Field ageField = null; nameField = c1.getDeclaredField("name"); // 取得name属性 ageField = c1.getDeclaredField("age"); // 取得name属性 nameField.setAccessible(true); // 此属性对外部可见 ageField.setAccessible(true); // 此属性对外部可见 nameField.set(obj, "沉缘"); // 设置name属性内容 ageField.set(obj, 25); // 设置age属性内容 System.out.println("姓名:" + nameField.get(obj)); System.out.println("年龄:" + ageField.get(obj)); }};
输出:
姓名:沉缘
年龄:25
可见,操作属性,未必需要setter和getter方法的支持,但是,为了保证程序的安全性,最好还是通过setter和getter方法对属性进行操作。
四、 通过反射操作数组
反射机制不光能用在类中,也可以应用在任意的引用数据类型上,当然,这就包含了数组,数组使用Array类完成。
Class类中存在以下一个方法:
public Class<?> getComponentType()
Array类中得到数组指定下标的内容:
public static Object get(Object array, int index) throws IllegalArgumentException, ArrayIndexOutOfBoundsException
Array类中修改内容:
public static void set(Object array, int index, Object value) throws IllegalArgumentException, ArrayIndexOutOfBoundsException
Array类中开辟新的数组:
public static Object newInstance(Class<?> componentType, int... dimensions) throws IllegalArgumentException, NegativeArraySizeException
取得数组信息并修改内容:
package org.chen.yuan.reflect;import java.lang.reflect.Array ;public class ClassArrayDemo{public static void main(String args[]) throws Exception{int temp[] = {1,2,3} ;// 声明一整型数组Class<?> c = temp.getClass().getComponentType() ;// 取得数组的Class对象System.out.println("类型:" + c.getName()) ;// 取得数组类型名称System.out.println("长度:" + Array.getLength(temp)) ;System.out.println("第一个内容:" + Array.get(temp,0)) ;Array.set(temp,0,6) ;System.out.println("第一个内容:" + Array.get(temp,0)) ;}};输出:
类型:int
长度:3
第一个内容:1
第一个内容:6
数组修改的过程,实际上就是创建一个新的数组的过程,所以要把旧的数组内容拷贝到新的数组中去。
package org.chen.yuan.reflect;import java.lang.reflect.Array;public class ChangeArrayDemo{ public static void main(String args[]) throws Exception { int temp[] = {1, 2, 3};// 声明一整型数组 int newTemp[] = (int[]) arrayInc(temp, 5); // 重新开辟空间5 print(newTemp); System.out.println("\n-------------------------"); String t[] = {"chenyuan", "wuqing", "lengxue"}; String nt[] = (String[]) arrayInc(t, 8); print(nt); } public static Object arrayInc(Object obj, int len) { Class<?> c = obj.getClass(); Class<?> arr = c.getComponentType(); // 得到数组的 Object newO = Array.newInstance(arr, len); // 开辟新的大小 int co = Array.getLength(obj); System.arraycopy(obj, 0, newO, 0, co); // 拷贝内容 return newO; } public static void print(Object obj) { // 数组输出 Class<?> c = obj.getClass(); if (!c.isArray()) { // 判断是否是数组 return; } Class<?> arr = c.getComponentType(); System.out.println(arr.getName() + "数组的长度是:" + Array.getLength(obj)); // 输出数组信息 for (int i = 0; i < Array.getLength(obj); i++) { System.out.print(Array.get(obj, i) + "、"); // 通过Array输出 } }};
输出:
nt数组的长度是:5
1、2、3、0、0、
-------------------------
java.lang.String数组的长度是:8
chenyuan、wuqing、lengxue、null、null、null、null、null、
- Java反射机制(三):调用对象的私有属性和方法
- Java记录 -88- 利用反射机制调用对象的私有方法和属性
- Java反射学习总结二(用反射调用对象的私有属性和方法)
- Java反射机制,通过对象访问调用类的私有成员属性或者方法
- 利用java的反射机制调用类的私有方法及私有属性
- 关于java的反射,调用私有方法(有参数私有方法),私有属性
- 转:用反射调用对象的私有属性和方法(经典)
- Java通过反射调用其他类的私有属性和私有方法
- Java反射的三种实现方式,访问私有方法和私有属性
- 反射(四)使用反射机制调用对象的私有方法及成员变量
- java反射机制(访问私有字段和私有方法)
- Java反射机制获取/调用类的属性和方法
- Java反射机制——获取Class对象,属性和方法(三)
- Java反射机制调用私有方法
- java反射机制调用私有方法
- 利用java反射机制调用类的私有方法
- JAVA反射机制调用源类的私有方法
- java如何利用反射机制调用类的私有方法
- C++之shared_ptr总结
- linux下apache+openssl配置记录
- 学习rails笔记
- Block --------- 1
- wordpress中,阿里云服务器实现自动邮件回复评论
- Java反射机制(三):调用对象的私有属性和方法
- DSP6000的几个简单优化技巧
- java基础之File对象中的FilenameFilter文件过滤以及递归列出指定文件夹路径下的所有文件和所有文件夹
- 数字信号处理的学习资源
- html/css知识lesson1
- C语言中尽量不要在头文件中定义变量
- SqlServer更改机器名后如何修改数据库的机器名
- 北大"小师妹"走红 网友赞许预备役校花
- 调试node 代码的方式