Java反射机制
来源:互联网 发布:权志龙的淘宝店叫什么 编辑:程序博客网 时间:2024/05/20 10:53
Java反射机制
反射概念:(百度百科)JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
作用:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
反射机制在API 需要的类:
java.lang.Class;
java.lang.reflect.Constructor;
java.lang.reflect.Field;
java.lang.reflect.Method;
java.lang.reflect.Modifier;
下面我们通过几个实例来描述java反射机制都能做哪些事情。
利用反射机制对ReflectTester类的customer对象进行拷贝:
import java.lang.reflect.Field;import java.lang.reflect.Method;public class ReflectTester { // 该方法实现对 customer对象的拷贝 public Object copy(Object object) throws Exception { Class<?> classType = object.getClass();//获得 Object类的类对象 Object objectCopy = classType.getConstructor(new Class[] {}).newInstance(new Object[] {}); // 先通过类对象对不带参数的构造方法获得其constructor对象,再通过构造方法对象 // 调用实例化方法生成对customer类的对象,并转成object类型的 所以objectCopy是object类型的引用 // ,但指向customer类,也就是多态。 // Object object2=classType.newInstance();上面两句等同于这一句 Field[] fields = classType.getDeclaredFields(); // 获得指定类(Object)的所有成员变量 for (Field field : fields) { // 增强的for循环 对存储customer成员变量的数组进行遍历 ,并打印输出 String name = field.getName(); String firstLetter = name.substring(0, 1).toUpperCase();// substring方法是获得对应字符串的在该下标范围内的字符 [0,1) // toUpperCase方法是将属性的首字母转换成大写 String getMethodName = "get" + firstLetter + name.substring(1);// 这个1表示1到末尾的字符 String setMethodName = "set" + firstLetter + name.substring(1);//字符串拼接 Method getMethod = classType.getMethod(getMethodName, new Class[] {});// customer类里面的getName方法是无参方法,获得指定方法的方法对象,括号内的getMethodName就是我们想要获得的方法的方法名,后面的Class类的数组就是该方法的参数 Method setMethod = classType.getMethod(setMethodName, new Class[] { field.getType() });// setMethodName方法是有参方法,getType方法是返回field的类型 Object value = getMethod.invoke(object, new Object[] {});// 这里的object是一开始传入的customer,getName方法无参,也就是通过invoke方法调用指定的方法,也就是Customer类里面的所有成员变量的get方法,最后得到object对象里面的具体数值信息然后赋给value对象, setMethod.invoke(objectCopy, new Object[] { value });// 将value里面的值传给objectCopy对象,通常情况下只要我们new一个对象,该对象里面都会包含一份对应类的成员变量,我们将面从get方法里面返回的数值重新赋给objectCopy里面的成员变量,也就完成了copy操作 } return objectCopy; } public static void main(String[] args) throws Exception { Customer customer = new Customer("Tom", 20); customer.setId(1L); ReflectTester test = new ReflectTester(); Customer customer2 = (Customer) test.copy(customer); System.out.println(customer2.getId() + "," + customer2.getName() + "," + customer2.getAge()); }}class Customer { private Long id; private String name; private int age; public Customer() { } public Customer(String name, int age) { this.name = name; this.age = age; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; }}
代码中的注释对代码解释已经很详细我就不在说了。接下来在看第二个例子,功能是实现调用某类的方法:
这里写import java.lang.reflect.Method;public class InvokeTester{ public int add(int param1, int param2) { return param1 + param2; } public String echo(String message) { return "hello: " + message; } public static void main(String[] args) throws Exception { // InvokeTester test = new InvokeTester(); // System.out.println(test.add(1, 2)); // System.out.println(test.echo("tom")); //下面那么多行代码其实就等同于上面几行代码 Class<?> classType = InvokeTester.class;//获得对应类的类对象 Object invokeTester = classType.newInstance();//获得指定类的实例 // System.out.println(invokeTester instanceof InvokeTester); Method addMethod = classType.getMethod("add", new Class[] { int.class,int.class });//通过括号内的限制,获得指定方法的方法对象 Object result = addMethod.invoke(invokeTester, new Object[]{1, 2});//对指定方法进行调用, System.out.println(result); System.out.println("---------------------"); Method echoMethod = classType.getMethod("echo", new Class[]{String.class}); Object result2 = echoMethod.invoke(invokeTester, new Object[]{"tom"}); System.out.println((String)result2); }}
再看第三个例子,功能是给某类的私有变量赋值:
public class Private2{ private String name = "zhangsan"; public String getName() { return name; }}import java.lang.reflect.Field;public class TestPrivate2{ public static void main(String[] args) throws Exception { Private2 p = new Private2(); Class<?> classType = p.getClass();//获得指定类的类对象 Field field =classType.getDeclaredField("name");//获得指定类里面的指定成员变量 field.setAccessible(true);//这里很重要,这里就使我们为什么能对私有化成员变量进行修改的主要原因,不明白得就去查看API文档 field.set(p, "lisi");//修改指定成员变量的值 System.out.println(p.getName()); }}
下一个例子是通过反射构建数组
import java.lang.reflect.Array;public class ArrayTester1 { public static void main(String[] args) throws Exception { Class<?>classTypeClass.forName("java.lang.String");//根据后面的字符串获得指定类的类对象 Object array = Array.newInstance(classType, 10);//这里的classtype是String,这句话的意思是创建一个String类型长度为10的数组 System.out.println(array instanceof String[]); for(int i=0;i<Array.getLength(array);i++) { String str = (String) Array.get(array, i); System.out.println(str); } Array.set(array, 5, "hello");//对数组某个位置上添加元素 String str = (String) Array.get(array, 5); System.out.println(str); }}
也不知道你们有没有耐心看到这里。。。。。。。
最后我就在总结一下反射机制的用法:
一般情况下 只要使用反射机制,我们都会先获得对应类的类对象,而获得类对象有三种方法:
a)使用 Class 类的静态方法 forName:Class.forName(“java.lang.String”);b)使用类的.class 语法:String.class;c)使用对象的 getClass()方法:String s = “aa”; Class<?> clazz = s.getClass();
若想通过类的不带参数的构造方法来生成对象,我们有两种方式:
a)先获得 Class 对象,然后通过该 Class 对象的 newInstance()方法直接生成即可:Class<?> classType = String.class; Object obj = classType.newInstance();b)先获得 Class 对象,然后通过该对象获得对应的 Constructor 对象,再通过该 Constructor 对象的 newInstance()方法生成:Class<?> classType = Customer.class;Constructor cons = classType.getConstructor(new Class[]{}); Object obj = cons.newInstance(new Object[]{});
若想通过类的带参数的构造方法生成对象,只能使用下面这一种方式:
Class<?> classType = Customer.class;Constructor cons = classType.getConstructor(new Class[]{String.class, int.class}); Object obj = cons.newInstance(new Object[]{“hello”, 3});
至于一些其他的方法也基本都在上面代码中,我就不在一一列出来。
不正确的地方大家多多指教。
阅读全文
1 0
- 【反射】JAVA反射机制
- 【Java】JAVA反射机制
- Java 反射机制[Field反射]
- Java 反射机制[Method反射]
- Java反射机制笔记-反射机制
- java的反射机制
- Java的反射机制
- java反射机制详解!
- Java反射机制
- Java的反射机制
- java 反射机制--侯捷
- java反射机制
- java反射机制
- [候捷]Java反射机制
- java 反射机制
- java 反射机制初探
- 关于Java反射机制
- java反射机制
- 数字在排序数组中出现的次数
- 常识性算法一弹
- 欢迎使用CSDN-markdown编辑器
- RecyclerView baseadapter
- 从头开始搭建一个dubbo+zookeeper平台
- Java反射机制
- Android Fragment使用小结及介绍
- Java总结 1104/1105
- 51Nod-1635-第K个幸运排列
- 三分钟教你读懂汇票是什么
- vs2015配置Opencv3.3.1
- 单例模式
- 6.8
- c语言笔记_2017年11月9日