------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ------
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
反射把Java类中的各种成分映射成相应的Java类,例如一个Java类中用一个Class类的对象表示,一个类中的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的Java类来表示。表示Java的Class类要提供一系列的方法,来获得其中的变量、方法、构造方法,修饰符、包等信息,这些信息就是用相应的类的实例对象来表示,他们是Field、Method、Contructor、Package等等。
1、Class类
java的Class类是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息。 虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。
下面是获得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() :获得所有的构造函数
2、Constructor类
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()); }
3、Filed类
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); } }
5、Method类
当获得某个类对应的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的简单应用。