黑马程序员-Java反射学习

来源:互联网 发布:mac 进入屏保 编辑:程序博客网 时间:2024/04/29 13:12

1.反射的定义

    Java中的成分映射成Java类。

2.Class类

 (1) Class 没有公共构造方法。Class 对象是在加载类时由 Java 虚拟机以及通过调用类加载器中的 defineClass 方法自动构造的,因此不能显式地声明一个Class对象。基本的 Java 类型(boolean、byte、char、short、int、long、float 和 double)和关键字 void 也都对应一个 Class 对象。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。

(2)获取Class类的三种方法:

A:MyObject x;

       Class c1 = x.getClass();

B:Class c2=Class.forName("MyObject");

C: Class cl2 = int.class;

代码:String str1="abc";           //定义一个String类
Class cls1=String.class;    //获取String类的第一种方法
Class cls2=str1.getClass();      //获取String类的第二种方法
Class cls3=Class.forName("java.lang.String");// 获取String类的第三种方法

System.out.println(cls1==cls2);   //如果是true 则第一种方法和第二种方法相同

         System.out.println(cls1==cls3);  //如果输出是true 第一种方法和第三种方法相同

 System.out.println(cls1);

(3)Class类的常用方法

A:getName()

B:newInstance()

C:isArray()

3.Constructor类

(1)表示一个类中的构造方法

(2)作用:获得所有或者某个构造方法。

(3)代码:Constructor constructor=String.class.getConstructor(StringBuffer.class);//获取StringBuffer类的构造方法

4.Field类

(1)定义:代表某个类中的成员变量。

(2)把String类型中的c改为d

代码:public String str1="ball";  
           public String str2="basketball";  
           public String str3="itcast";  
           public String toString(){  
                return str1+":"+str2+":"+str3;  

          }  

       public class ReflectTest {  
        public static void main(String[] args)throws Exception{  
        ReflectPoint rp=new ReflectPoint();  
        changeStringValue(rp);  
        System.out.println(rp);  
    }  
  
    private static void changeStringValue(Object obj) throws Exception {  
        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);  
            }  
        }  
    }  
}  


5.Method类

(1)定义:Method类代表类中的成员方法。

(2)得到类中的某一个方法:

           Method  m=Class.forName("java.lang.String").getMethod("chatAt",int.class);

(3)调用方法:

           invoke方法。

(4)代码:String str1="abc";
Method method1=String.class.getMethod("abcd", int.class);
System.out.println(method1.invoke(str1, 1));

6.用反射的方式执行某个类中的main方法

(1)问题

        启动JAVA程序的main方法的参数是一个字符串数组,即public static void main(String [] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的方法,数组中的每个元素对应该一个参数,当把一个字符串组作为参数给invoke方法时,javac会到底按照哪种语法进行处理呢?

(2)解决办法

mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});

mainMethod.invoke(null,(Object)new String[]{"xxx"};);,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了。
7.数组的反射
(1)代码:

final int []a = {10,12,13,14,15};  //定义一个数组 
        Object o = a;  
        System.out.println(Array.getLength(o));    //输出数组的长度
        for(int i=0;i<Array.getLength(o);i++) {  
            System.out.print(Array.get(o, i)+" ");    // 输出数组
        }  
        System.out.println();  
        Array.setInt(o, 4, 16);    //把O中第5个数字改为16
        for(int i=0;i<Array.getLength(o);i++) {  
            System.out.print(Array.get(o, i)+" ");  //最后一个数子改为16
        }  
        System.out.println(); 
8.HashCode分析
(1)hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的;
(2)如果两个对象相同,就是适用于equals(java.lang.Object) 方法,那么这两个对象的hashCode一定要相同;
(3)如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就          会违反上面提到的第2点;
(4)两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列           存储结构中,如Hashtable,他们“存放在同一个篮子里”
9.反射的用途
(1)作用:可以通过一个类名来探察这个类里面的信息,比如说类的属性名,属性名的修饰符,方法名,方法返回值,方法修饰符等等,反射还可以 生成类的实例,通过这个实例定义属性,调用方法,特别是能调用私有的属性和私有的方法。(2)实现框架功能,调用与被调用



0 0
原创粉丝点击