在面向对象的世界里,万事万物都是对象,那么,在JAVA语言中,静态成员,普通的数据类型是不是对象呢?如果是,他们是谁的对象呢?其实,类也是对象,它是java.long.Class类的实例对象。
Class类的实例表示正在运行的Java应用程序中的类和接口,他没有公共构造方法,要创建Class类的对象,可以有三种方法,分别如下:
1,使用类的Class属性
Class c = Deom.class;
2,使用Class类的forName方法
try{
Class c = Class.forName("test.Demo");//括号里面的参数是包名.类名
}catch(ClassNotFoundException e1){
e1.printStackTrace():
}
使用Class类的forName方法创建Class对象时,需要捕获ClassNotFoundException异常。
3,使用Object对象的getClass方法
Demo demo = new Demo();
Class c = demo.getClass();
以上三种方法都可以创建Class类的对象,但他们创建的反射对象是完全相同的,也就是说:一个类只能有一个反射对象,例如,使用以上3中方法分别创建同一个类的反射对象,并分别输出他们的哈希码值。
可以看到,这是三个对象的哈希吗是完全相同的,因为一个类只能有一个反射对象。
利用Class类的对象就可以返回该对象所代表的类的描述信息,可以访问的主要描述信息如下表。
在通过方法getFields()和getMethods()依次获得权限为public的成员变量和方法时,将包含从超类中继承到的成员变量和方法,而通过方法getDeclaredFields()和getDeclaredMethods()只是获得在本类中定义的所有成员变量和方法。
获取构造方法
获取类的构造方法可以使用Class类提供的getConstructors方法,getConstructor方法,getDeclaredConstructors方法和getDeclaredConstructor方法实现,它们将返回Constructor类型的对象或数组,他们的使用方法如下:
1,getConstructors():返回一个包含某些Constructor对象的数组,这些对象反映此Class对象所表示的类的所有公共构造方法。
2,getConstructor(Class<?>…parameterTypes):返回一个Constructor对象,它反映此Class对象所表示的类的指定公共构造方法。
3,getDeclaredConstructors():返回Construcotr对象的一个数组,这些对象反映此Class对象表示的类声明的所有构造方法。
4,getDeclaredConstructor(Class<?>…parameterTypes):返回一个Constructor对象,该对象反映此Class对象所表示的类或接口的指定构造方法。
如果是访问指定的构造方法,需要根据该构造方法的入口参数的类型来访问。例如,访问一个入口参数类型依次为String和int型的构造方法,通过下面两种方式均可实现。
objectClass.getDeclaredConstructor(String.class,int Class);
objectClass.getDeclaredConstructor(new Class[]{String.class,int.class});
没个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应的构造方法。Constructor类中提供的常用方法如下表:
通过java.lang.reflect.Modifier类可以解析出getModifiers()方法的返回值所表示的修饰符信息,在该类中提供了一系列用来解析的静态方法,既可以查看是否被指定的修饰符修饰,还可以以字符串的形式获得所有修饰符。该类常用的静态方法如下表:
例如,判断对象constructor所代表的的构造方法是否被private修饰,以及以字符串形式获得该构造方法的所有修饰符的代码如下:
int modifiers = constructor.getModifiers();
boolean isEmbellishByPrivate = Modifier.isPrivate(modifiers);
String embellishment = Modifier.toString(modifiers);
看一个例子。
接下来再写一个测试类,在该类中通过反射获取这个类中的所有构造方法,并将该构造方法是否允许带有可变数量的参数,如果参数和可能抛出的异常类型信息输出到控制台。
获取成员变量
获取类的成员变量可以使用Class类提供的getFields方法,getField方法,getDeclaredFields方法和getDcelaredField方法实现,他们将返回Field对象的数组,他们的使用说明如下。
1,getFields():返回一个包含某些Field对象的数组,这些对象反映此Class对象所表示的类或接口的所有可访问公共字段。
2,getField(String name):返回一个Field对象,它反映此Class对象所表示的类或接口的指定公共成员字段。
3,getDeclaredFields():返回Field对象的一个数组,这些对象反映此Class对象所表示的类或接口所声明的所有字段。
4,getDeclaredField(String name):返回一个Field对象,该对象反映此Class对象所表示的类或接口的指定已声明字段。
如果是访问指定的成员变量,可以通过该成员变量的名称来访问,例如,访问一个名称为birthday的成员变量,访问方法如下:
Object.getDeclaredField("birthday");
没个Field对象代表一个成员变量,利用Field对象可以草丛相应的成员变量。Field类中提供的常用方法如下:
我们来看一个例子。
首先在一个类中放一些成员变量。
在本例中,会发现在访问权限为private的成员变量s时,需要执行setAccessible方法,并将入口参数设为true,否则不允许访问。
获取方法
获取类的方法可以使用Class类提供的getMethods方法,getMethod方法,getDeclaredMethods方法和getDeclaredMethods方法和getDeclaredMethod方法实现,他们将返回Method类型的对象或数组,他们的使用说明如下。
1,getMethods():返回一个包含某些Method对象的数组,这些对象反映此Class对象所表示的类或接口(包含那些有该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共成员方法。
2,getMethod(String name,Class<?>…parameterTypes):返回一个Method对象,它反映此Class对象所表示的类或接口的指定公共成员方法。
3,getDeclaredMethods():返回Method对象的一个数组,这些对象反映此Class对象表示的类或接口声明的所有方法,包括公共,保护,默认和私有方法,但不包括继承的方法。
4,getDeclaredMethod(String name,Class<?>…parameterTypes):返回一个Method对象,该对象反映此Class对象所表示的类或接口的指定已声明方法。
如果是访问指定的方法,需要根据该方法的名称和入口参数的类型来访问,例如,访问一个名称为print,如果参数类型依次为String和int型的方法,通过下面两种方式均可实现:
objectClass.getDeclaredMethod("print",String.class,int.class);
objectClass.getDeclaredMethod(“print”,new Class[]{String.class,int.class});
每个Method对象代表一个方法,利用Method对象可以操纵相应的方法。Methods类中提供的常用方法如下表:
我们来看一个例子,首先定义一个类,并编写4个典型的方法。
我们再编写另外一个类,通过反射获取上面类中的所有方法。
注意,在反射中执行具有可变数量的参数的构造方法时,需要将入口参数定义成二维数组。