java反射
2016-05-24 10:49
549 查看
Java反射(反射就是把Java类中的各种成分映射成相对应的Java类)
该文章根据张孝祥老师在课程中提到的知识点进行总结
所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制。这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field)、方法(Method)以及调用其中的方法,也可以设置其中的属性值。
Java中实现反射的几种方法:
注意:所有得类的对象都是地址(字节码),所以用不同方法反射出来的同一个对象, 都是相同的。
1、 通过Class.forName(“”)方法加载字符串,就可以得到该字符串所代表的类的对象;
注意:字符串必须为类的全名 = 包名 + 类名
2、通过类名调用class属性得到该类的Class对象。
3、通过实例的getClass()方法
4、如果是基本类型的包装类,则可以通过调用包装类的TYPE属性来获得该包装类的对象
(数据类型对应的包装类 Integer, Double, Boolean, Byte, Short, Character, Long, Float)
Constructor 获取反射对象的构造方法
使用Constructor得到需要反射对象的构造方法 然后使用其对象.newInstance创建出Object实例 然后就可以直接使用
使用newInstance直接使用反射的对象.newInstance()创建出Object实例
Field类 可以获取对象中的共有属性
语法:
Method类,获取对象实例中的所有方法(同获取属性一样)
对接受数组类型参数的方法进行反射调用
注意: 因为执行的是main方法,所以这里invoke首个参数为空.
对数组进行反射
如有遗漏,谢谢补充,共同学习,共同进步。
该文章根据张孝祥老师在课程中提到的知识点进行总结
所谓反射,是指在运行时状态中,获取类中的属性和方法,以及调用其中的方法的一种机制。这种机制的作用在于获取运行时才知道的类(Class)及其中的属性(Field)、方法(Method)以及调用其中的方法,也可以设置其中的属性值。
Java中实现反射的几种方法:
注意:所有得类的对象都是地址(字节码),所以用不同方法反射出来的同一个对象, 都是相同的。
1、 通过Class.forName(“”)方法加载字符串,就可以得到该字符串所代表的类的对象;
注意:字符串必须为类的全名 = 包名 + 类名
String str = Class.forName("java.lang.String");
2、通过类名调用class属性得到该类的Class对象。
Class cla = String.class;
3、通过实例的getClass()方法
String str = new String(""); Class cla = str.getClass();
4、如果是基本类型的包装类,则可以通过调用包装类的TYPE属性来获得该包装类的对象
(数据类型对应的包装类 Integer, Double, Boolean, Byte, Short, Character, Long, Float)
Class cla = Integer.TYPE;
Constructor 获取反射对象的构造方法
使用Constructor得到需要反射对象的构造方法 然后使用其对象.newInstance创建出Object实例 然后就可以直接使用
Constructor con = String.class.getConstructor(StringBuffer.class);
使用newInstance直接使用反射的对象.newInstance()创建出Object实例
Class.forName("java.lang.String").newInstance();
Field类 可以获取对象中的共有属性
语法:
Object obj = new Object(); //声明一个对象实例 Field field = obj.getClass().getField("公共属性"); //获取到对象的字节码(字节码中包含方法变量等..) 调用获取属性的方法 getField(); Field field1 = obj.getClass.getDeclaredField("所有属性都可以"); //不管是私有属性,或者共有属性,都可以获取到 field1.setAccessible(true); 如果访问的是私有属性必须加上这句 强力访问 System.out.println(field.get(obj)); //使用field获取某个对象的属性值 小实例:(获取Object的所有属性,并且将属性的value值进行替换) public class ClassDemo{ public String a = "123"; public String b = "345"; private String c = "456"; public String toString(){ return "a: " + a + "b: " + b + "c: " + c; } } public static void main(String[] args){ ClassDemo cla = new ClassDemo(); Field[] field = cla.getClass().getDeclaredFields(); //获取到所有的属性 for(Field fie : field){ fie.setAccessible(true); if(fie.getType() == String.class){ //判断如果属性的类型是String类型的【这个地方用==是因为String类型只会产生一个字节码直接用==即可,当然也可以用equeals】 String oldValue = (String)fie.get(cla); String newValue = oldValue.replace('b', 'a'); fie.set(cla, newValue); } } }
Method类,获取对象实例中的所有方法(同获取属性一样)
ClassDemo clas = new ClassDemo(); Method method = clas.getClass().getMethod("toString", null); String str = (String)method.invoke(clas, null);
对接受数组类型参数的方法进行反射调用
注意: 因为执行的是main方法,所以这里invoke首个参数为空.
public class a{ public static void main(String[] args){ Method method = Class.forName("com.class.b").getMethod("main", String[].class); //这里为什么要先把String数组强转成Object? 如果不强转则会报 java.lang.IllegalArgumentException: wrong number of arguments异常。 //因为b.main方法中接受的是一个String类型的数组,但是在执行过程中他会把传过来的数组解析(打开)识别成传过来两个String类型的参数 所以这个地方必须强转。 --1. method.invoke(null, (Object)new String[]{"111", "222"}); --2. method.invoke(null, new Object[]{new String[]{"111", "222"}}); } } class b { public static void main(String[] args){ for(String arg : args){ System.out.println(arg); } } }
对数组进行反射
public class test{ public static void main(String[] args){ Object obj = new Object[]{"111", 11, 'a'}; shuzeReflect(obj); } public static void shuzeReflect(Object obj){ if(obj.getClass().isArray()){ //首先判断传入的参数是不是数组 int leng = Array.getLength(obj); //如果是数组,则获取该数组的length for (int i = 0; i < leng; i++) { System.out.println("数组中的Value : " + Array.get(obj, i)); //print.. 111, 11, a System.out.println("数组中Value的类型" + Array.get(obj, i).getClass().getName()); //print java.lang.String, Integer, Character } } else { System.out.println(obj); } } }
如有遗漏,谢谢补充,共同学习,共同进步。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树