反射
反射可以在程序运行时获取一个类的各个组成部分(成员变量、构造方法、成员方法),然后执行相关的操作。
每个类的字节码本身就是一个对象用Class表示,而类的各个组成部分也都是对象,分别用Field表示成员变量,Constructor表示构造方法,Method表示成员方法。学习反射就是学习这些对象的使用。
- 1.获取字节码对象(Class)
- 2.获取构造方法对象并使用(Constructor)
- 3.获取成员变量对象并使用(Field)
- 4.获取成员方法对象并使用(Method)
获取字节码
//类名.class
Class cls1=Student.class;
//对象名.getlass();
Student stu=new Student();
Class cls2=stu.getClass();
//Class.forname("类的全路径名")
Cla cls3=Class.forname("xx.Student");
获取类的构造方法对象
public Constructor[] getConstructors()
获取所有公有的构造方法
public Constructor[] getDeclaredConstructors()
获取所有的构造方法(包括私有的)
public Constructor getConstructor(Class<?> cls...)
获取一个公有的构造方法
public Constructor getDeclaredConstructor(Class<?> cls...)
获取一个构造方法(可以私有的)
- 利用反射获取Student类的构造方法并使用
public class Student {
private String name;
int age;
public String sex;
public Student() {
}
public Student(String name,String sex,int age){
this.name=name;
this.age=age;
this.sex=sex;
}
private Student(String name, int age) {
this.name = name;
this.age = age;
}
}
public class Demo1{
public static void main(String[] args){
Class<?> clazz = Class.forName("com.itheima02.Student");
//获取空参数的公有的构造方法
Constructor<?> con = clazz.getConstructor();
//利用空参数的构造方法创建对象,等价于 Student stu=new Student()
Student stu= (Student) con.newInstance();
System.out.println(stu);
System.out.println("--------------");
//获取3个参数的公有的构造方法,参数String类型,String类型,int类型
Constructor<?> con3 = clazz.getConstructor(String.class, String.class, int.class);
//利用3个参数的构造方法创建对象,等价于Student stu3=new Student("张三","男",18);
Student stu3 = (Student) con3.newInstance("李四", "男", 18);
System.out.println(stu3);
System.out.println("--------------");
//获取带有2个参数的私有构造方法
Constructor<?> con2 = clazz.getDeclaredConstructor(String.class, int.class);
//暴力反射(取消权限检查)
con2.setAccessible(true);
//利用2个参数的构造方法创建对象,等价于 Student stu2=new Student("张三",20);
Student stu2= (Student) con2.newInstance("张三",20);
System.out.println(stu2);
}
}
获取类的成员变量对象
public Field[] getFields()
获取所有公有的成员变量
public Field[] getDeclaredFields()
获取所有的成员变量(包括私有的)
public Field getField(String fieldname)
获取一个公有的成员变量
public Field getDeclaredField(String fieldname)
获取一个成员变量(可以私有的)
- 反射获取成员变量并使用
public class Person {
//这里定义了3个变量
public String name;
int age;
private String sex;
public Person() {
}
public Person(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
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;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
public class Demo {
public static void main(String[] args) throws Exception {
//获取字节码对象
Class<?> clazz = Class.forName("XX.Person");
//创建Person类对象
Constructor<?> con = clazz.getConstructor();
Person p = (Person) con.newInstance();
//获取名称为name的成员变量
Field fname = clazz.getField("name");
//p.setName("zhangsan");
fname.set(p,"zhangshan");
//p.getName();
String feldNameValue = (String)fname.get(p);
System.out.println(feldNameValue);
//获取名称为age的成员变量
Field fage = clazz.getDeclaredField("age");
fage.set(p,11);
Integer i = (Integer) fage.get(p);
System.out.println(i);
System.out.println(p);
System.out.println(".....");
//获取名称为sex的成员变量
Field fsex = clazz.getDeclaredField("sex");
fsex.setAccessible(true);
fsex.set(p,"男");
String fsexValue = (String)fsex.get(p);
System.out.println(fsexValue);
}
}
反射获取成员方法
public Method[] getMethods()
获取所有公有的成员方法(包括父类方法)
public Method[] getDeclaredMethods()
获取所有的成员方法(包括私有的)
public Method getMethod(String name,Class... clss)
获取一个公有的成员方法
public Method getDeclaredMethod(String name,Class... clss)
获取一个成员方法(可以私有的)
- 反射获取成员方法并使用
public class Student {
public void show(){
System.out.println("show show ...");
}
public void show(String str,int a){
System.out.println("show...."+str+"...."+a);
}
int sum(int n){
int sum=0;
for (int i = 0; i <=n; i++) {
sum+=i;
}
return sum;
}
private void sir(){
System.out.println("不是吧,啊sir");
}
}
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> clazz = Class.forName("XX.Student");
//反射获取构造方法
Constructor<?> con = clazz.getConstructor();
//创建对象
Student stu = (Student) con.newInstance();
//反射获取show的无参方法
Method show = clazz.getMethod("show");
show.invoke(stu);
//反射获取show的有参方法
Method show1 = clazz.getMethod("show", String.class, int.class);
show1.invoke(stu,"wo",12);
//反射获取sum方法
Method sum = clazz.getDeclaredMethod("sum", int.class);
int invoke = (int)sum.invoke(stu, 10);
System.out.println(invoke);
//反射获取sir方法
Method sir = clazz.getDeclaredMethod("sir");
sir.setAccessible(true);
sir.invoke(stu);
}