反射是 Java中非常重要的一个语言特性,反射强大和完善让 Java语言在工程实践 中的灵活性大增强, 使得 Java 程序在运行时可以探查类的信息, 动态创建对象程序在运行时可以探查类的信息, 动态创建对象获知对象的属性,调用方法 获知对象的属性,调用方法 。因此,反射技术被广泛的应用在一些工具和框架开发 上。
要理解反射,首先需要理解的是“类”对象的概念。什么是“类”对象,我们知道一个类可以创建多个实例,每个实例就是一个对象,其实可以这么简单的理解:孙悟空有一个技能,拔根毫毛可以变幻出很多孙悟空,这里的变幻出的孙悟空可以看做是一个类的实例,而真正的那个有72般变化的孙悟空就是一个类。但是从另外一个角度来说,孙悟空虽然是类,单他也是一个对象,一个孙悟空对象。
接下来,我们介绍一如何获得类对象。
总共有三种方式
1、类名.class
可以通过类名 .class的方法 直接获得某个类的对象。例如,如果要获得Student类的对象,就可以使用
Class c=Student.class。
这种方法获得类对象比较直接,并且还有一个非常重要的特点。对于基本类型来说,他们也有自己的类对象,但是要获得基本类型的类对象,只能通过类型名.class来获得类对象。例如,通过下面的代码就能获得int类型的类对象。
Class c=int.class
2、getClass()方法
Object类中定义了一个 getClass() 方法,这个也能获得类对象。我们之前曾经介绍过这个方法,前文中把称之为获得对象的实际类型。而现在我们可以知道,这个方法实际上是返回某个对象的类对象。
当我们有一个对象,而想要获得这个对象的类对象的时候,应当调用这个对象的getClass()方法,因此getClass()方法主要用于:通过类的对象获取类对象。
3、Class.forName()方法
在Class类中有一个静态方法,这个静态方法叫做forName,方法的签名如下:
public static Class forName(String ClassName) throws ClassNotFoundException
这个方法接受一个字符串作为参数,这个字符串参数表示一个类的类名,这个静态方法能够根据一个类名返回相应的类对象。需要注意的两点是:
1、当classname所代表的类不存在的时候,这个方法会抛出一个已检查异常的ClassNotFoundException
2、这个方法 接受的字符串作为的参数,必须含包名,例如:需要使用Class.forName("java.util.ArrayList")而不是使用Class.forName("ArrayList")。
得到类对象之后,接下来是如何使用类对象。
一、类对象可以调用以下方法,例如:
1、getName():获得类的名称,包括包名
2、getSimpleName():获得类的名称,不包括包名
3、getSuperClass():获得本类的父类的类对象
4、getInterfaces():获得本类所实现的所有接口的类对象,返回值类型是Class[],当然,一个类可以实现多个接口。
如下代码:
import java.util.ArrayList;
public class TestClass1 {
public static void main(String[] args) {
Class c = ArrayList.class;
String className = c.getName()
System.out.println(" 类名: "+className);
String simpleName = c.getSimpleName();
System.out.println(" 简单类名: "+simpleName);
Class superClass = c.getSuperclass();
System.out.println("父类: "+superClass.getName());
Class[] interfaces = c.getInterfacs();
System.out.print System.out.print ln (" 接口: ");
for(int i =0 ; < interfaces.length i++){
System.out.println(interfaces[i].getName());
}
}
}
输出:
类名:java.util.ArrayList
简单类名:ArrayList
父类:java.util.AbstractList
接口: java.util.List
java.util.RandomAccess
java.lang.Cloneable
java.io.Serializable
二、使用类对象获取类中方法的信息
在Class类中,有两个方法,这两个方法如下:
public Method[] getDeclaredMethods() throws SecurityException -----方法1
public Method[] getMethods() throws SecurityException -----方法2
方法1获取当前类对象的所有方法,包括私有的方法,但是不能获取父类的任何方法,方法2获取所有的公共方法,包括父类中定义的公开的方法。
例如如下用法:
import java.lang.reflect.*;
public class TestReflection {
public static void main(String[] args) {
Class c = Student.class;
Method[] ms = c.getDeclaredMethods();
for(int i = 0; i<ms.length; i++){
System.out.println(ms[i].toString());
}
}
}
来获取Student类中的方法。
此处输出结果:略
三、使用类对象创建的使用类对象
例如,如果要创建一个对象,我们除了new之外还可以如下创建:
Class c=Student.class
Student u=(Student)c.newInstance();
这样创建对象的时候,会调用对象的无参构造方法。