Class类
在Java中所有的反射操作都是围绕Class类来展开的,Class这个类是在JDK1.0的时候出现的,可以说这个类是Java类中的元老李,那么这个类究竟有什么特别之处呢?查看文档发现Class类是一个final类,也就是我们所说的太监类,不可能有子类,但是虽说没有子类,但是却仍与所有的类都有着关系。Class定义如下:
-
public final class Class<T> extends Object implements Serializable, GenericDeclaration, Type, AnnotatedElement
好吧,处理Serializable,其他都看不懂,就先过滤掉吧!
一、取得Class对象
所以的类都是Object类的子类,在Object类中有一个getClass方法,通过此方法可以获得Class类,所以说Class类虽说没有子类,但却能通过Object类间接的与所有的类有关系。
- Object的getClass方法:public final Class<?> getClass()返回的是一个Class对象。调用该方法必须先实例化对象
- 使用Class字面常量:类名.class得到Class对象
- 使用Class类的静态方法:Class.forName("类")。不需要实例化
这三种方法都是可以获取Class对象,前两种比较安全,因为要使用前两种就必须先导入所要使用的类,例如:我要使用Date类,那么就必须先 import java.util.Date,----编译器会检查这个类,如果不存在会报错。而使用Class.forName不需要提前导入需要的类,不管类存不存在都不会报错,这个只在运行时才报错,所以使用时要抛异常。虽说还有较多区别,但是这里仅仅补充我所学到的。将来需要再补充。
下面是代码:
public static void getClassObject() {
// 三种取得Class对象的方式
try {
Class<?> cls1 = Class.forName("java.util.Date");
System.out.println(cls1.getName());
System.out.println(cls1.getSimpleName());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Class<?> cls2 = Date.class;
System.out.println(cls2.getName());
Class<?> cls3 = new Date().getClass();
System.out.println(cls3.getName());
}
二、java.lang.reflect反射包
Java的反射机制可以说是一个重要的概念,利用反射,程序可以在运行状态中调用查看一个类的所有属性与方法(静态)以及调用任意一个对象的属性与方法。在Java中提供了java.lang.reflect包对反射的支持,在反射包中有几个常用的类:Constructor、Method、Field。使用他们可以随时创建对象,使用对象,以及修改对象属性。
1、Constructor
Construct定义如下:
public final class Constructor<T> extends Executable
Constructor同Class一样也是一个final类,且构造方法私有化 ,Constructor常用方法定义及使用如下:
public static void getConstructor() {
// 获取类的构造方法
Class<?> cls;
try {
cls = Class.forName("Basketball");
// Constructor con = cls.getConstructor();// 取得类的指定构造,可带参数
Constructor<?>[] cons = cls.getConstructors();// 取得全部构造
// Constructor<?>[] cons = cls.getDeclaredConstructors();//取得当前类的构造
for (int i = 0; i < cons.length; i++) {
System.out.println("构造函数名:" + cons[i].getName());
System.out.println("参数个数:" + cons[i].getParameterCount());
Type[] type = cons[i].getParameterTypes();
System.out.println("参数类型:");
for (int y = 0; y < type.length; y++) {
System.out.println("\t" + type[y].toString());
}
System.out.println("当前类:" + cons[i].getDeclaringClass());
System.out.print("构造方法修饰符:" + cons[i].getModifiers());
// 输出结果为1,代表public,但是将构造方法改成private和protected均不输出所以放弃
// 若要输出结果为public则可以使用toString方法
System.out.println("----" + Modifier.toString(cons[i].getModifiers()));
try {
// 实例化对象
Object obj = cons[i].newInstance("篮球");
System.out.println("实例化对象:" + obj.toString());
} catch (Exception e) {
Object obj;
try {
obj = cons[i].newInstance();
System.out.println("实例化对象:" + obj.toString());
} catch (Exception e1) {
}
}
// 获取异常对象
Class<?>[] exp = cons[i].getExceptionTypes();
System.out.println("获取异常:");
for (int y = 0; y < exp.length; y++) {
System.out.println("\t" + exp[i].getName());
}
System.out.println("****************************");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
运行结果:
2、Method
Method定义如下:
public final class Method extends Executable
常用方法及使用:
public static void getClassMethod() {
try {
Class<?> cls = Class.forName("Basketball");
Method[] methods = cls.getMethods();// 这个类所有的方法
System.out.println("当前类所对应的方法修饰符、返回值、方法名以及参数:");
for (Method method : methods) {
StringBuffer sbuffer = new StringBuffer();
sbuffer.append("\t");
sbuffer.append(Modifier.toString(method.getModifiers())).append(" ");// 方法修饰符
sbuffer.append(method.getReturnType().getSimpleName()).append(" ");// 方法返回值
sbuffer.append(method.getName()).append("(");
Class<?>[] types = method.getParameterTypes();// 获取全部参数类型
if (types.length > 0) {
for (int i = 0; i < types.length; i++) {
sbuffer.append(types[i].getSimpleName()).append(" argv" + i + ",");
}
sbuffer.delete(sbuffer.length() - 1, sbuffer.length());
}
sbuffer.append(");");
System.out.println(sbuffer.toString());
}
System.out.println("调用特定的方法--invoke");
// 取得某一方法:参数1 方法名称,参数2方法参数类型(无参数可省略),此处直接写
try {
Basketball ball = new Basketball();
cls.getMethod("setName", String.class).invoke(ball, "篮球");
System.out.println(cls.getMethod("getName").invoke(ball));
} catch (Exception e) {
e.printStackTrace();
}
// 略:getExceptionTypes();getParameterCount() ;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
运行结果:略
3.Field
Field定义如下:
public final class Field extends AccessibleObject implements Member
与Constructor不同的是Field直接继承AccessibleObject并且实现Member接口,而Constructor与Method都是间接继承AccessibleObject。
常用方法使用如下:
public static void getField() {
try {
Class<?> cls = Class.forName("Basketball");
Object obj = cls.newInstance();
// 取得全部成员,只能取得public修饰的变量
Field[] fields = cls.getFields();
for (Field field : fields) {
System.out.println(field);
System.out.println("获取属性的内容" + field.get(obj));
}
System.out.println("********************");
Field field = cls.getDeclaredField("name");
/**
* 设置属性的内容.pass:直接设置出现异常 </br>
* java.lang.IllegalAccessException: Class Reflect can </br>
* not access a member of class Basketball with modifiers "private"</br>
* name使用private封装,外部无法访问
* <li>方法1:将private改为public,虽然能解决但是不建议</li>
* <li>方法2:使用setAccessible(true);
*/
field.setAccessible(true);// 取消封装,该方法由父类java.lang.reflect.AccessibleObject 提供
field.set(obj, "篮球");
System.out.println("获取属性的内容" + field.get(obj));
} catch (Exception e) {
e.printStackTrace();
}
}
后续后面补充