java反射学习--操作私有成员
2013-06-19 10:11
471 查看
反射,reflection,听其名就像照镜子一样,可以看见自己也可以看见别人的每一部分。在java语言中这是一个很重要的特性。
反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。
java中有一个类很特殊,就是Class类,很多朋友在写程序的时候有用过比如Hello.class来查看类型信息,大家就可以把它理解为封装了类的信息,很多解释说Class类没有构造器,其实是有的,只不过它的构造方法是private的(构造函数还有private的??有,这样是为了禁止开发者去自己创建Class类的实例)。
/*
* Constructor. Only the Java Virtual Machine creates Class
* objects.
*/
private
Class() {}
Class类是由虚拟机创建的,不需要我们去显示创建。
好了,先看一个简单的反射例子:
输出:
这里注意:forName中的参数一定是完整的类名(包名+类名),并且这个方法需要捕获异常。
当没有创建对象的时候,获取类类型的方法
Class<?> c = Class.forName("java.lang.String");
Class<?> c = String.class;
好了,看一个具体的案例吧,
描述一下这个案例的简单要实现的功能:
DataType.java类中提供几个私有的字段(未提供set和get方法),用另外一个类,修改这几个字段的值,.我们要实现的就是使用反射的方法来访问这些Fields 和Methods.
首先我们先使用不带参数的构造方法
输出结果:int n=100 String str=I love java String[] sArr=xiaoming xiaohong zhangsan List<Integer> list=0 1 2
如果用带参数的构造方法来完成相同的功能,
输出结果:int n=100 String str=I love java String[] sArr=xiaoming xiaohong zhangsan List<Integer> list=0 1 2
反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。
java中有一个类很特殊,就是Class类,很多朋友在写程序的时候有用过比如Hello.class来查看类型信息,大家就可以把它理解为封装了类的信息,很多解释说Class类没有构造器,其实是有的,只不过它的构造方法是private的(构造函数还有private的??有,这样是为了禁止开发者去自己创建Class类的实例)。
/*
* Constructor. Only the Java Virtual Machine creates Class
* objects.
*/
private
Class() {}
Class类是由虚拟机创建的,不需要我们去显示创建。
好了,先看一个简单的反射例子:
import java.lang.reflect.Method; public class ShowMethod { public static void main(String[] args) throws Exception { Class<?> c = Class.forName("java.lang.Object"); Method[] methods = c.getDeclaredMethods(); for(Method method : methods){ System.out.println(method); } } }
输出:
private static native void java.lang.Object.registerNatives() public final native java.lang.Class java.lang.Object.getClass() public native int java.lang.Object.hashCode() public boolean java.lang.Object.equals(java.lang.Object) protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException public java.lang.String java.lang.Object.toString() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll() public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException public final void java.lang.Object.wait() throws java.lang.InterruptedException public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException protected void java.lang.Object.finalize() throws java.lang.Throwable
这里注意:forName中的参数一定是完整的类名(包名+类名),并且这个方法需要捕获异常。
当没有创建对象的时候,获取类类型的方法
Class<?> c = Class.forName("java.lang.String");
Class<?> c = String.class;
好了,看一个具体的案例吧,
描述一下这个案例的简单要实现的功能:
DataType.java类中提供几个私有的字段(未提供set和get方法),用另外一个类,修改这几个字段的值,.我们要实现的就是使用反射的方法来访问这些Fields 和Methods.
import java.util.List; public class DataType { private int n; private String str; private String[] sArr; private List<Integer> list; public DataType(){} public DataType(int n, String str, String[] arr, List<Integer> list) { this.n = n; this.str = str; sArr = arr; this.list = list; } public String toString(){ StringBuilder sb = new StringBuilder(); sb.append("int n=").append(this.n).append(" "); sb.append("String str=").append(this.str).append(" "); sb.append("String[] sArr="); for(int i=0;i<sArr.length;i++){ sb.append(sArr[i]).append(" "); } sb.append("List<Integer> list="); for(int i=0;i<list.size();i++){ sb.append(list.get(i)).append(" "); } return sb.toString(); } }
首先我们先使用不带参数的构造方法
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; public class MyTest { public static void main(String[] args) throws Exception { int n=100; String str = "I love java"; String[] sArr = new String[]{"xiaoming","xiaohong","zhangsan"}; List<Integer> list = new ArrayList<Integer>();//0 1 2 for(int i=0;i<3;i++){ list.add(i); } Class<DataType> clazz = DataType.class; //获取默认的构造方法对象 Constructor<DataType> cons = clazz.getConstructor(new Class[]{}); //运行不带参数的构造方法,创建对象实例 DataType dataType = cons.newInstance(new Object[]{}); //获取所有的字段 Field[] fields = clazz.getDeclaredFields(); //为每一个字段赋值 for(Field field : fields){ //首先设置该字段的可访问性 field.setAccessible(true); if(field.getType().getSimpleName().equals("int")){ field.set(dataType, n); }else if(field.getType().getSimpleName().equals("String")){ field.set(dataType, str); }else if(field.getType().getSimpleName().equals("String[]")){ field.set(dataType, sArr); }else if(field.getType().getSimpleName().equals("List")){ field.set(dataType, list); } } //获取toString方法 Method toStringMethod = clazz.getMethod("toString", new Class[]{}); Object result = toStringMethod.invoke(dataType, new Object[]{}); System.out.println(result); } }
输出结果:int n=100 String str=I love java String[] sArr=xiaoming xiaohong zhangsan List<Integer> list=0 1 2
如果用带参数的构造方法来完成相同的功能,
//获取带参数的构造方法对象 Constructor<DataType> cons2 = clazz.getConstructor(new Class[]{int.class,String.class,String[].class,List.class}); DataType dataType2 = cons2.newInstance(new Object[]{n,str,sArr,list}); Object result2 = toStringMethod.invoke(dataType2, new Object[]{}); System.out.println(result2);
输出结果:int n=100 String str=I love java String[] sArr=xiaoming xiaohong zhangsan List<Integer> list=0 1 2
相关文章推荐
- Java学习笔记_反射_Class.forName()加载并修改一个类的私有成员变量
- Java反射操作私有成员变量 Class can not access a member with modifiers "private"
- java中反射操作私有成员变量
- 通过Java反射测试类私有成员(新)
- java中反射操作公共成员变量
- JAVA中的反射机制对私有成员的访问
- JAVA基础学习之IP简述使用、反射、正则表达式操作、网络爬虫、可变参数、了解和入门注解的应用、使用Eclipse的Debug功能(7)
- 黑马程序员——【Java反射学习】方法的反射/成员变量的反射/构造函数的反射
- JAVA学习--反射方法操作
- java反射访问私有成员变量
- java中的反射机制——如何访问私有成员的私有方法
- 黑马程序员--Java基础加强--16.利用反射操作泛型V【通过Constructor反射解析泛型构造方法】【通过Field反射解析泛型成员变量】【个人总结】
- Java反射访问私有成员
- Java反射学习总结二(用反射调用对象的私有属性和方法)
- 通过Java反射测试类私有成员
- 利用反射机制操作私有成员变量(private修饰的变量)
- Java反射学习总结(3)——反射的基本操作
- Java反射学习-使用反射修改一个类中的所有String类型的成员变量的值
- JAVA学习--反射构造器操作
- 类反射学习(三) JAVA如何利用类反射调用普通函数、访问成员成员变量