黑马程序员-反射
来源:互联网 发布:js打开窗口 编辑:程序博客网 时间:2024/06/05 07:41
---------------------- Android培训、java培训、期待与您交流! ----------------------
反射:
Class类:
java程序中的各个java类属于同一类事物,描述这类事物的java类名就是Class。
class类的实例对象对应各个类在内存中的字节码。
字节码:一个类被类累加器加载到内存中,占用一片存储空间,这个空间中的内容就是类的字节码。
获取字节码对应的Class类型的实例对象的方法:
1,类名.class
2,,对象.get|Class()
3,Class.forName("类名")
9个预定义Class实例对象:
int, long, byte, short, float, double, char, boolean, void
只要是在源程序中出现的类型都有各自的class实例对象,如: int[], void。
String str1 = "abc";Class cls1 = str1.getClass();Class cls2 = String.class;Class cls3 = Class.forName("java.lang.String");System.out.println(cls1 == cls2);//trueSystem.out.println(cls1==cls3);//trueSystem.out.println(cls1.isPrimitive());//false.不是基本数据类型。System.out.println(int.class.isPrimitiver());//true.System.out.println(int.class==Interger.class);//false.System.out.println(int.class==Interger.TYPE;//trueSystem.out.println(int[].class.isPrimitive());//false.System.out.println(int[].class.isArray());//true
反射:
就是把java类中的各种成分映射或java类。
例如:一个java类中用一个class类的对象来表示一个类中的组成部分:成员变量,方法,构造方法,包等也用一个个java类来描述,表示java类的class类提供了一系列方法来获得这些信息对应的类。它们是Field, Method, Contructor, Package.
Constructor类
代表某个类中的构造方法:
1,得到所有构造方法:
Constructor[] constructors = Class.forNaem("java.lang.String").getConstructors();
2,得到一个构造方法:
Constructor constructor =Class.forNaem("java.lang.String").getConstructor(SringBuffer.class);
3,创建对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式:String str = (String)Constructor.newInstance(new StringBuffer("abc"));//调用获得的方法要用到上面相同类型的实例对象。
4,Class.newInstance()方法:、
String obj = (String)Class.forName("java.lang.String").newInstance();//该方法内容先得到默认的构造方法,然后用该构造方法创建实例对象。内部用到了缓存机制来保存默认构造方法的实例对象。
Constructor constructor1 = String.class.getConstructor(StringBuffer.class);String str1 = (String)Constructor1.newInstance(new StringBuffer("abc");Stytem.out.println(str1.charAt(2));//c
Field类:
代表某个类的一个成员变量。
注:得到的Field对象是对应到类上面的成员变量。
class ReflectPoint{private int x;private int y;public ReflectPoint(int x,int y){this.x = x;this.y = y;}}public static void main(String[] args){ReflectPoint pt1 = new Reflect(3,5);Field fieldY = pt1.getClass().getField("Y");//fieldY不是对象的变量而是类上的。System.out.println(fieldY.get(pt1));//得到pt1对象上Y的值。}
练习:将任意一个对象中的所有String类型的成员变量所对应的内容只能给的"b"替换成"a":
public void changeStringValue(Object obj){Field[] fields = obj.getClass.getFields();//得到所有字段。for(Field field: fields){if(field.getType()==String.class){String oldValue = (String)field.get(obj);String newValue = oldValue.replace('b','a');field.set(obj.newValue);}}}
Method类:
代表某个类中的一个成员方法。
1,得到类中某个成员方法。
2,调用方法。
普通方式:Str.charAt();
反射方式:methodCharAt.invoke(str,1);如果传递给invoke的第一个参数为null,表示method对象对应一个静态方法。
String str1 = "abc";method methodCharAt = String.class.getMethod("charAt",int.class);System.out.println(methodChatAt.invoke(str1,1));//b
jdk1.4与1.5的invoke方法区别:
1.5:public static Object invoke(Object obj, Object...args)
1.4:public static Object invoke(Object obj, Object[] args)
即:1.4的语法需要将一个数组作为参数传递给invoke方法,数组中的每个元素分别对应被调用方法中的一个参数。
所以调用charAt方法的代码也可以用1.4改写成charAt.invoke(str,new Object[]{1}形式。
使用反射方式调用某个类的main方法:
String startingClassName = args[0];Method mainMethod = class.forName(startingClassName).getMethod("main",String[].class);mainMethod.invoke(null,(Object)new String[]{"111","222","333"});//如不加(Object)。jre会按照1.4语法将String[]拆成3个字符串参数。还有另一个解决方法。Object[] {new String[]{"111","222","333"}}
数组与Object的关系及其反射类型:
int[] a1 = new int[]{1,2,3};int[] a2 = new int[4];int[][] a3 = new int[2][3];String[] a4 = new String[]{"a","b","c"};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());//[ISystem.out.println(a1.getClass().getSuperclass().getName());//java.lang.ObjectSystem.out.println(a4.getClass().getSuperclass().getName());//java.lang.ObjectObject o1 = a1;//编译通过。Object o2 = a4;//通过。Object o3 = a1;//报错。Object o4 = a3;//通过。Object o5 = a4;//通过。
打印数组:将数组转换成List后便于打印内容。
System.out.println(Arrays.asList(a1));//[[I@1cfb549]System.out.println(Arrays.asList(a4));//[a.b.c]/*a1无法打印出数组内容的原因:Arrays类的asList()方法在1.4的语法:public static List asList(Object[] a)1.5的语法:public static <T> List<T> asList(T...a)a1为int[]基本数据类型数组,1.4的语法不符所以采用了1.5的语法,将数组看成一个元素存入List.*/
对数组的反射:
数组类:java.lang.reflect.Array
实现一个可以打印所有类型数据功能的方法,并能打印出数组内容。:
public static void printObject(Object obj){class c = obj.getClass();if(c.siArray){int len = Array.getLength(obj);for(int x=0; x<=len; x++){System.out.println(Array.get(obj,i));}}else{System.out.println(obj);}}
hashCode:
通过哈希算法来提高从集合中查找元素的效率,这种方法将集合分成若干个存储区域,根据一个对象的哈希码就可以确定该对象应该存储在哪个区域。
HashSet就是采用哈希算法存取对象的集合。Object类中定义了一个hashCode方法来返回每个java对象的哈希码,当从HashSet集合只能给查找某个对象时,
java系统先调用对象的hashCode方法获得对象的哈希值,找到相应的存储区域,最后取出该存储区域内每个元素与该对象进行equals方法比较。
hashCode 可能导致内存泄露:
当参与hashCode值计算的字段值发生变化时,使集合中元素的哈希值改变,当remove该元素时,将无法找到该元素导致无法删除,使内存泄露。
---------------------- Android培训、java培训、期待与您交流! ----------------------
- 黑马程序员--java 反射
- 黑马程序员之反射
- 黑马程序员之反射
- 黑马程序员__java_反射
- 黑马程序员_反射
- 黑马程序员 反射
- 黑马程序员--Java反射
- 黑马程序员--反射
- 黑马程序员-java-反射
- 黑马程序员:反射技术
- 黑马程序员_java反射
- 黑马程序员---反射
- 黑马程序员-反射
- 黑马程序员---反射
- 黑马程序员_反射
- 黑马程序员_反射
- 黑马程序员:反射
- 黑马程序员_反射
- 基于visual Studio2013解决算法导论之012计数排序
- 搜集Win7系统与安卓手机wifi共享问题的解决方法
- Android ART虚拟机
- POJ3067--Japan(树状数组)
- LinkedList ArrayList Vector的比较
- 黑马程序员-反射
- GUI程序中添加控制台调试
- 导出excel调用模版
- fdisk 命令
- java基础--笔记6
- android jar包封装引用
- java基础--笔记7
- xml操作类,具体用法看注释
- ArcSDE10.1使用st_geometry环境配置