保存类信息的类是Class
getClass()将返回一个调用对象相关的Class实例
Class对象表示的是一种类型,这个类型不一定是对象类型,例如 int.class 是一个Class类型对象
虚拟机为每个类型管理一个Class对象,因此可以直接使用 == 来进行比较
Employee e = new Employee();
e.getClass().newInstance();
newInstance方法创建了一个和 e 相同类型的实例,将会调用默认构造器,如果没有默认构造器将抛出异常
Class类中的getFields、getMethods和getConstructors方法将分别返回类提供的public域、方法和构造器数组且包括基类的公有成员
getDeclareFields、getDeclareMethods和getDeclareConstructors将返回类中声明的域、方法和构造器,包括private和protected,但不包括基类成员
getModifiers将会返回一个int类型的值,再使用Modifier类的 toString方法可以得到,域、方法和构造器前修饰的关键字
下面的类通过反射根据类名来解析类中的构造器、方法、域
public class ClassAnalyzer {
private final String tab = " ";
public String toString(String className) {
Class> cl = null;
try {
cl = Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return this.toString(cl);
}
public String toString(Class cl) {
StringBuilder builder = new StringBuilder();
Class supercl = cl.getSuperclass();
int classInt = cl.getModifiers();
String classModifier = Modifier.toString(classInt);
if (classModifier.length() > 0) {
builder.append(classModifier).append(" ");
}
builder.append("class ").append(cl.getName());
if (supercl != null && supercl != Object.class) {
builder.append(" extends ").append(supercl.getName());
}
StringBuilder consBuilder = printConstructors(cl);
StringBuilder methodsBuilder = printMethods(cl);
StringBuilder fieldsBuilder = printFields(cl);
builder.append(" {\n").append(fieldsBuilder).append(methodsBuilder).append(consBuilder).append("}");
return builder.toString();
}
private StringBuilder printConstructors(Class cl) {
StringBuilder builder = new StringBuilder();
Constructor[] constructors = cl.getDeclaredConstructors();
for (Constructor constructor : constructors) {
String name = constructor.getName();
builder.append(tab);
int constructorInt = constructor.getModifiers();
String consModifier = Modifier.toString(constructorInt);
if (consModifier.length() > 0) {
builder.append(consModifier).append(" ");
}
builder.append(name).append(" (");
Class[] paramTypes = constructor.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) {
builder.append(", ");
}
builder.append(paramTypes[i].getName());
}
builder.append(");\n");
}
return builder;
}
private StringBuilder printMethods(Class cl) {
StringBuilder builder = new StringBuilder();
Method[] methods = cl.getDeclaredMethods();
for (Method method : methods) {
Class> returnType = method.getReturnType();
String typeName = returnType.getName();
if (typeName.startsWith("[")){//数组会显示为[开头
typeName = typeName.substring(2);
typeName = typeName.replace(";", "[]");//将;结尾替换为[]结尾
}
String name = method.getName();
builder.append(tab);
int methodInt = method.getModifiers();
String methodModifier = Modifier.toString(methodInt);
if (methodModifier.length() > 0) {
builder.append(methodModifier).append(" ");
}
builder.append(typeName).append(" ").append(name).append(" (");
Class>[] paramTypes = method.getParameterTypes();
for (int i = 0; i < paramTypes.length; i++) {
if (i > 0) {
builder.append(", ");
}
builder.append(paramTypes[i].getName());
}
builder.append(");\n");
}
return builder;
}
private StringBuilder printFields(Class cl) {
StringBuilder builder = new StringBuilder();
Field[] fields = cl.getDeclaredFields();
for (Field field : fields) {
Class> type = field.getType();
String typeName = type.getName();
if (typeName.startsWith("[")){
typeName = typeName.substring(2);
typeName = typeName.replace(";", "[]");
}
String name = field.getName();
builder.append(" ");
int fieldInt = field.getModifiers();
String fieldModifier = Modifier.toString(fieldInt);
if (fieldModifier.length() > 0) {
builder.append(fieldModifier).append(" ").append(typeName).append(" ");
}
builder.append(name).append("\n");
}
return builder;
}
}
返回值如下
public class Chapter5.Employee {
private double salary
private java.time.LocalDate hireday
private java.lang.String name
private Chapter5.Workday[] workdays
public void raiseSalary (double);
public Chapter5.Employee (double, java.lang.String, int, int, int);
}
以上是对类进行解析,如果要对类的某个对象进行解析呢
try {
Employee stark = new Employee(2000, "stark", 2020, 5, 22);
Class extends Employee> employee = stark.getClass();
Field name = employee.getDeclaredField("name");
Object starkName = name.get(stark);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//运行将会抛出异常Class Main can not access a member of class Chapter5.Employee with modifiers "private"
异常原因就是Employee中的name属性访问权限为private
但是使用反射可以绕开这个限制来获取它的值,使用setAccessible(true)
try {
Employee stark = new Employee(2000, "stark", 2020, 5, 22);
Class extends Employee> employee = stark.getClass();
Field name = employee.getDeclaredField("name");
name.setAccessible(true);
Object starkName = name.get(stark);//starkName实际是字符串"stark"
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
下方的类通过反射对对象进行解析
public class ObjectAnalyzer {
private ArrayList
除了解析类和对象外,通过反射还能调用任意方法,当然,这是不推荐使用的