码迷,mamicode.com
首页 > 其他好文 > 详细

黑马程序员——高新技术---反射

时间:2015-03-31 00:43:20      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

黑马程序员——高新技术---反射

 

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------

 

一、概述

  JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

  反射把Java类中的各种成分映射成相应的Java类,例如一个Java类中用一个Class类的对象表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示。表示Java的Class类要提供一系列的方法,来获得其中的变量、方法、构造方法,修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们是Field、Method、Contructor、Package等等。

 

二、正文

1Class

      java的Class类是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息。 虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。

      下面是获得Class对象的三种方式:

  1. 用Object类的getClass()方法来得到Class对象,这也是最常见的产生Class对象的方法。例如: Class c1 = x.getClass();
  2. 使用Class类的中静态forName()方法获得与字符串对应的Class对象。例如: Class c2=Class.forName("某个类的完整类名”)
  3. 获取Class类型对象的第三个方法非常简单。如果T是一个Java类型,那么T.class就代表了匹配的类对象。例如:    Class cl2 = int.class;

  下面是Cl14ass类的方法:

1. public static Class<?> forName(String className) :natice 方法,动态加载类。非常重要
2. public T newInstance() :根据对象的class新建一个对象,用于反射。非常重要
3. public ClassLoader getClassLoader() :获得类的类加载器
4. public String getName() :获取类或接口的名字
5. public native Class getSuperclass():获取类的父类,继承了父类则返回父类,否则返回
6. public java.net.URL getResource(String name) :根据字符串获得资源
7. public boolean isEnum() :判断是否为枚举类型
8. public native boolean isArray() :判断是否为数组类型
9. public native boolean isPrimitive() :判断是否为基本类型
10. public native int getModifiers() : 反射中获得修饰符
11. public Field getField(String name):反射中获得域成员
12. public Field[] getFields() :获得域数组成员
13. public Method[] getMethods() :获得方法
14. public Constructor<?>[] getConstructors() :获得所有的构造函数

  

2Constructor

  Constructor 类是各种类的构造方法的反射类。Constructor 反射类对象的获得,例如:

  Constructor constructor=String.class.getConstructor(StringBuffer.class);

  构造方法可以用于构造实例对象,例如:

  String str=(String)constructor.newInstance(new StringBuffer("abc"));

  Class本身也还有newInstance方法,可以直接调用,例如:

  String obj=(String)String.class.newInstance(); //类似于调用无参的构造方法。

  下面是一段简单的示例代码:

//通过Constructor对象来创建类实例方法

public static void ConstructorDemo() throws Exception{

       //获取Test类的Class对象

       String className = "cn.itheima.Test";

       Class clazz = Class.forName(className);

             

       //获取指定构造函数的类实例

       Constructor con = clazz.getConstructor(String.class,int.class);

       Test p = (Test) con.newInstance("lisi",30);

       System.out.println(p.toString());

}

 

3Filed

      Java通过Class对象的getFileds()或getField()方法可以获取该类所包括的全部Field或指定的Filed。下面是两种方法来读取或设置Field的值:

1. getXxx(Object obj):获取obj对象该Field的属性值。此处的Xxx对应8个基本类型,如果该属性的类型是引用类型,则取消get后面的Xxx。
2. setXxx(Object obj,Xxx val):将obj对象的该Field设置成val值。此处的Xxx对应8个基本类型,如果该属性的类型是引用类型,在取消set后面的Xxx。

  下面是一段简单的示例代码:

public class Test {

       public final int a=5;

       public static void main(String[] args) {

              Test test = new Test();

              try {  

                      //指定要获取的字段名

                            Field field = Test.class.getField("a");

                            //从Test对象中获取一个整形值;

                            System.out.println(field.getInt(test));

                            //如果不能确定是什么数据类型可以返回一个Object

                            Object obj = field.get(test);

                            System.out.println(obj);

                            //获取对象的数据类型

                            System.out.println(obj.getClass().getName());

  } catch (Exception e) {

              e.printStackTrace();

  }

 }

}

 

 

4、操作数组

      在java.lang.reflect包下提供了一个Array类,Array对象可以代表所有的数组。程序可以通过使用Array来动态地创建数组,操作数组元素等。Array提供了如下几类方法:

1. static Object newInstance(Class<?> componentType,int…length):创建一个具有指定的元素类型、指定维度的新数组
2. Static xxx getXxx(Object array,int index):返回array数组中第index个元素。其中xxx是各种基本数据类型,如果数组元素是引用类型,则该方法变为       get(Object array,int index)
3. static void setXxx(Object array,int index,xxx val):将array数组中第index个元素的值设为val。其中xxx是各种数据类型,如果数组元素是引用类         型,则该方法变成set(Object array,int index,xxx val)

  下面是一段代码:打印传入对象,如果为单一对象,直接打印,如果为数组,则逐一打印数组元素(对数组对象的判断应用)

public void printObject(Object obj){

       Class cla=obj.getClass();

      

       if(cla.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);

      }

}

 

5Method

      当获得某个类对应的Clss对象后,就可以通过该Class对象的getMethods()方法或者getMethod()方法来获取全部方法或指定方法(这两个方法的返回值是Method数组),或者Method对象。

      具体方法如下:

1. Method[] getMethods(); //只获取公共和父类中的方法

2. Method[] getDeclaredMethods(); //获取本类中包含私有

3. Method  getMethod("方法名",参数.class(如果是空参可以写null))

4. Object invoke(Object obj ,参数); //该方法obj是执行该方法的主调,后面的是实参

  下面是一段示例代码:得到类中的某一个方法。

public class ReflectMethod{

    public static void main(String args[]) throws Exception{

      

          //new String[]{new String("abc"),new String("xyz"),new String("mn")}; //String数组

       //new Object[]{new String("abc"),1}; //Object数组

     

         String str1 = "abcd";

      

          //str1.chatAt(1);

      

          Method methodCharAt = String.class.getMethod("charAt",int.class);

      

          char c = (Character)methodCharAt.invoke(str1,new Object[]{2});

           //使用jdk1.4的语法调用,传一个Object数组进去

      

          System.out.println(c);//c

    }

}

 

三、总结

  本文简单的讲述了反射的基本概念,以及反射的基础Class的三种获取方式和常用的方法,还讲述了和反射相关的四个类Filed、Method、Array和Constructor的简单应用。

黑马程序员——高新技术---反射

标签:

原文地址:http://www.cnblogs.com/hutanlong/p/4379063.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!