反射
来源:互联网 发布:程序员和运维工程师 编辑:程序博客网 时间:2024/05/20 13:09
反射的概述:
Java类用于描述一类事物的共性,该类事物有什么属性,没有什么属性,至于这个属性的值是多少,则由这个类的实例对象来确定。
Java程序中的各个java类,他们是否属于一类事物,描述这类事物的java类名就是Class
如何得到各个字节码对象对应的实例对象(Class类型)
1、类名.class 例如:Class class1 =Person.class//字节码1;
2、对象.getClass() 例如:P1.getClass();
3\Class.forName(“类名”) 例如:Class.forName(“java.lang.String”);//作用:返回类字节码
有两种形式可以得到字节码
1、 字节码 已经加载到内存中,找到字节码返回;
2、 没有加载到内存中,用类加载器加载到内存中,缓存字节码,用返回字节码。
- 数组类型的Class实例对象
class.isArray()
总之,只要是在源程序中出现的类型,都有各自的Class实例对象
String str1 = "abc";Class class1 =str1.getClass();Class class2 =String.class;Class class3 =Class.forName("java.lang.String");System.out.println(class1==class2); //trueSystem.out.println(class1==class3); //trueSystem.out.println(class1.isPrimitive()); //falseSystem.out.println(int.class.isPrimitive()); //基本类型trueSystem.out.println(int.class==Integer.class); //falseSystem.out.println(int.class==Integer.TYPE); //常量trueSystem.out.println(int[].class.isPrimitive()); //false System.out.println(int[].class.isArray()); //true
反射就是把java类中的各种成分映射成相应的java类。
例如:一个java类中用一个Class类的对象来表示,一个类中的组成部分:成员变量,方法,构造方法,修饰符、包等信息用一个个的java类来表示。
//编译器只看变量的定义不看代码的执行
- Constructor 类代表某个类中的一个构造方法
1)得到某个类所有的构造方法:
例子:
Constructor[] constructors = Class.forName(“java.lang.String”).getConstructor();//class—>constructor-->new object
2)得到某一个构造方法:
例子:
Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
3)创建实例对象
通常方式:String str = new String(new StringBuffer(“abcd”));
反射方式:String str =
(String)constructor. newInstance(new StringBuffer("abc"));
//调用获得的方法时要用到上面相同类型的实例对象
.newInstance()方法返回值类型是Object
//表示用这个构造方法时,传递的StringBuffer对象(同样类型的对象)
4)Class.newInstance()方法
例子:String obj = (String) Class.forName(“java.lang.String”).newInstance();
该方法内部先得到默认的构造方法,然后用构造方法创建实例对象。
用缓存机制保存默认构造方法的对象。
- 成员变量的反射:
Field类代表某个类中的一个成员变量
ReflectPoint pt1 = new ReflectPoint(3, 5);Field fieldY = pt1.getClass().getField("y");//fieldY 代表类字节码中的变量,不是对象本身的变量,而是类上,要用它去取某个对象的值System.out.println(fieldY.get(pt1));Field fieldX = pt1.getClass().getDeclaredField("x");fieldX.setAccessible(true);//暴力反射(变量为私有)看见了取不到 用暴力反射 System.out.println(fieldX.get(pt1));
public class ReflectPoint {private int x;public int y; public String str1 = "ball";public String str2 = "basketball";public String str3 = "itcast";//自动生成构造函数public ReflectPoint(int x, int y) {super();this.x = x;this.y = y;}} private static void changeStringValue(Object obj) throws IllegalArgumentException, IllegalAccessException {Field[] fields = obj.getClass().getFields();for(Field field:fields){//if(field.getType().euqals(String.class))//因为是同一份字节码if (field.getType()==String.class) {String oldValue = (String)field.get(obj);String newValue = oldValue.replace('b', 'a');field.set(obj, newValue);}} }
Method类代表某个类中的一个成员方法
1) 得到类中的某一个方法:
例子:Method charAt =
Class.forName(“java.lang.String”).getMethod(“charAt”,int.class);
2) 调用方法
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str,1));
如果传递给method对象的invoke()方法的第一个参数为null,则该method对象对应的是一个静态方法!
Jdk1.4与jdk1.5中invoke方法的区别(可变参数)
//拿出字节码的方法 再作用于某个对象Method methodCharAt = String.class.getMethod("charAt", int.class);System.out.println(methodCharAt.invoke(str1, 1));//jdk1.4的调用方法System.out.println(methodCharAt.invoke(str1,new Object[]{2})); //1.5 可变参数 methodCharAt.invoke(Object obj,Object[] args);
- 对接收数组参数的成员方法进行反射
用反射方式执行某个类中的main方法
class TestArguments {public static void main(String[] args) {for(String arg :args){System.out.println(arg);}}//调用main方法//TestArguments.main(new String[]{"123","345","sss"}); //用反射去调用 String startingStringClassName = args[0]; Method mainMethod = Class.forName(startingStringClassName).getMethod("main", String[].class);//方法1java兼容性 传递数组时拆封 mainMethod.invoke(null, new Object[]{new String[]{"ss","123"}});//方法2java兼容性 传递数组时拆封mainMethod.invoke(null,(Object)new String[]{"ss","123"});
- 数组的反射
数组字节码类型相同的要满足:
1·元素类型相同
2·维数相同
则它们具有相同的Class实例对象
注意:基本类型的一维数组可以被当作Object类型使用,不能当作能当作Object[]类型使用;非基本类型的一维数组,既可以当做Object类型使用,又可以做Object[]类型使用。
Arrays.aslist()方法处理int和String[]时的差异--
不能得到整个数组的类型 可以得到某个值的类型
例子:a[0].getClass().getName();
//数组 int[] a1 = new int[3]; int[] a2 = new int[4]; int[][] a3 = new int[2][3]; String[] a4 = new String[]{"ad","bd","cd"}; System.out.println(a1.getClass()==a2.getClass()); //true //System.out.println(a1.getClass()==a4.getClass());//false //System.out.println(a1.getClass()==a3.getClass());//false System.out.println(a1.getClass().getName()); System.out.println(a1.getClass().getSuperclass().getName());//Object System.out.println(a4.getClass().getSuperclass().getName());//Object Object aObj1 = a1; Object aObj2 = a4; //Object[] aObj3 = a1; int 不是object Object[] aObj4 = a3; Object[] aObj5 = a4; System.out.println(a1); System.out.println(a4); System.out.println(Arrays.asList(a1));//一个参数[I@1cfb549] System.out.println(Arrays.asList(a4));//[a,b,c] printlnObject(a4); printlnObject(123);//通用方法private static void printlnObject(Object obj) {Class clazz = obj.getClass();if (clazz.isArray()) {int len = Array.getLength(obj);for (int i = 0; i < len; i++) {System.out.println(Array.get(obj, i));}} else {System.out.println(obj);}
怎么得到数组的元素类型
Int[]a=new int[2]
直接用数组对象a无法得到
只能先得到一个元素的类型a[0].getClass().getName()
- ArrayList_HashSet的比较及Hashcode分析
Arraylist 无论对象是否相同,都可存入引用
Hashset 如果集合中已有该对象,则不再存入。
Hashcode 的作用:每个集合分区域 哈希值对应区域(提高查找效率)提高对集合操作的效率 (内存泄漏) (内存一直被占用)
计算Hashcode 值得参数一般不要改变,如果改变可能造成数据操作失败。
- 反射的作用--->实现框架功能
框架要解决的核心问题:利用反射
InputStream ips= new FileInputStream("config.properties");Properties ps = new Properties();ps.load(ips);ips.close();String className = ps.getProperty("className"); Collection collections = (Collection)Class.forName(className).newInstance();
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- 反射
- virtualbox 设置共享目录
- struct kset
- poj1094 拓扑排序
- android开发者需要收藏的网站
- 安装BO客户端 crystall report,dashboard,报错提示检测到操作未完成
- 反射
- 小学生之进位
- VMware vSphere部署的管理和优化迷你书
- hive 创建/删除/截断 表(翻译自Hive wiki)
- IIS站点cpu过高问题
- 进程VS线程
- 编程学习的好网站汇总
- Backbone.js学习笔记——View篇
- WIN32界面开发之三:DUI雏形开发(二)