Java的反射
每个类被加载后,系统都会为该类生成一个对应的Class对象,通过该Class对象可以访问到JVM中的这个类。获取Class对象有
三种方式:
- Class类的forName(String clazzName)静态方法
- 调用类的class属性
- 调用对象的getClass()方法
有了这个Class对象后就有了类的所有东西
定义一个Student类:
public class Student
{
private String name;
private int age;
public Student()
{
}
private Student(String name)
{
super();
this.name = name;
}
public Student(String name, int age)
{
super();
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("Student [name=");
builder.append(name);
builder.append(", age=");
builder.append(age);
builder.append("]");
return builder.toString();
}
}
获取Studnet类的所包含构造器
- Constructor getConstructor(Class… parameters)
返回此Class对象对应类带指定形参列表public构造器 - Constructor getConstructors()
返回此Class对象对应类所有public构造器 - Constructor getDeclaredConstructor(Class… parameters)
返回此Class对象对应类带指定形参列表构造器,与访问权限无关 - Constructor getDeclaredConstructors()
返回此Class对象对应类所有构造器,与访问权限无关
public class ReflectTest
{
public static void main(String[] args)
throws NoSuchMethodException, SecurityException
{
Class clazz = Student.class;
Constructor c1 = clazz.getConstructor(String.class, int.class);
System.out.println(c1);
Constructor[] c2 = clazz.getConstructors();
for (int i = 0; i < c2.length; i++)
{
System.out.println(c2[i]);
}
Constructor c3 = clazz.getDeclaredConstructor(String.class);
System.out.println(c3);
}
}
public Student(java.lang.String,int)
public Student()
public Student(java.lang.String,int)
private Student(java.lang.String)
获取Studnet类的所包含字段
- Field getField(String name)
返回此Class对象对应类指定名称的public成员变量 - Field[] getFields()
返回此Class对象对应类所以的public成员变量 - Field getDeclaredField(String name)
返回此Class对象对应类指定名称的成员变量,与成员变量访问权限无关 - Field[] getDeclaredFields()
返回此Class对象对应类所以的成员变量,与成员变量访问权限无关
public class ReflectTest
{
public static void main(String[] args)
throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException
{
Student student = new Student();
Class clazz = Student.class;
Field field = clazz.getDeclaredField("name");
// 取消访问权限检查,通过反射可以访问private成员
field.setAccessible(true);
field.set(student, "zhangsan");
System.out.println(student);
}
}
获取Studnet类的所包含方法
- Method getMethod(String name,Class parameters)
返回此Class对象对应类的带指定形参的public方法 - Method[] getMethods()
返回此Class对象对应类的所以的public方法 - Method getDeclaredMethod(String name,Class<?> parameters)
返回此Class对象对应类的带指定形参的方法,与访问权限无关 - Method[] getDeclaredMethods()
返回此Class对象对应类的所以的方法,与访问权限无关
public class ReflectTest
{
public static void main(String[] args)
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
Student student = new Student();
Class clazz = Student.class;
// 获得setName方法
Method method = clazz.getMethod("setName", String.class);
// 执行setName方法
method.invoke(student, "zhangsan");
System.out.println(student);
Method method2 = clazz.getMethod("toString");
System.out.println(method2);
}
}
使用反射创建对象
通过反射创建对象有两种方式
1.使用Class对象的newInstance()方法创建该Class对象对应类的实例,该方式要求该Class对象对应类要有默认的无参构造器
2.先获得指定的构造器对象,再通过构造器对象的newInstance()方法来创建对象对应类的实例
public class ReflectTest
{
public static void main(String[] args)
throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException,
IllegalArgumentException, InvocationTargetException
{
Class clazz = Student.class;
// 使用默认无参构造器创建对象
Student student1 = (Student)clazz.newInstance();
// 获得带字符串参数的构造器
Constructor ctor = clazz.getDeclaredConstructor(String.class);
ctor.setAccessible(true);
// 使用带字符串参数的构造器创建对象
Student student2 = (Student)ctor.newInstance("zhangsan");
// 获得带字符串和int参数的构造器
Constructor ctor2 = clazz.getDeclaredConstructor(String.class, int.class);
// 使用带字符串和int参数的构造器创建对象
Student student3 = (Student)ctor2.newInstance("zhangsan", 20);
System.out.println(student1);
System.out.println(student2);
System.out.println(student3);
}
}