Reflection(反射)可以在运行时获取一个类的所有信息,并且可以操作类的字段、方法和构造器等。
说明:追根溯源,使用的是Object类的getClass()方法,因为所有类都继承Object类,所以下面的子类也可以使用getClass()方法。
Student s = new Student();
Class cla = s.getClass();
说明:此处调用的是该类的class属性,获取该类对应的Class字节码对象。
Class cla = Student.class;
说明:使用java自带的Class类中的forName("类的路径")静态方法。
Class cla = Class.forName("类的路径");
。第一种方法对象已经存在,此时反射的价值不大。
第二种方法导入类的包,依赖性过强,耦合度高,没导报错。
第三种方法比较常用,安全且性能好。
package reflectTest;
/**
* @author:tengsen
* @create: 2022-10-08 21:19
* @Description:
*/
public class TestReflect {
public static void main(String[] args) throws ClassNotFoundException {
//通过Student类拿到字节码对象
Class> cla1 = new Student().getClass();
//通过类的class属性拿到字节码对象
Class> cla2 = Student.class;
//根据类的路径拿到字节码对象
Class> cla3 = Class.forName("reflectTest.Student");
System.out.println("cla1:"+cla1);
System.out.println("cla2:"+cla2);
System.out.println("cla3:"+cla3);
}
}
package reflectTest;
/**
* @author:tengsen
* @create: 2022-10-08 15:57
* @Description:
*/
public class Student {
private String id;
private String name;
public int age;
public String gender;
public double waterFee;
public Student() {
}
public Student(String id, String name, int age, String gender) {
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
waterFee=0;
}
public void study(){
System.out.println("学习ing");
}
public boolean rechargeWaterBill(double money){
waterFee+=money;
System.out.println("成功充值"+money+"元,水费余额:"+waterFee+"元");
return true;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
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 getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public double getWaterFee() {
return waterFee;
}
public void setWaterFee(double waterFee) {
this.waterFee = waterFee;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
", waterFee=" + waterFee +
'}';
}
}
1>字节码对象.getFields()。说明:得到公有属性。
2>字节码对象.getDeclareFields()。说明:得到所有属性,无论是公有还是私有。
package reflectTest;
import java.lang.reflect.Field;
/**
* @author:tengsen
* @create: 2022-10-08 21:38
* @Description:
*/
public class TestReflect2 {
public static void main(String[] args) throws ClassNotFoundException {
Class> cla = Class.forName("reflectTest.Student");
//getFields()得到公有属性
Field[] fields1 = cla.getFields();
System.out.println("getFields()的效果:");
for (Field field:fields1){
System.out.println("属性名:"+field.getName());
System.out.println("属性类型:"+field.getType());
System.out.println();
}
System.out.println();
//getDeclaredFields()得到所有属性,无论公有还是私有
Field[] fields2 = cla.getDeclaredFields();
System.out.println("getDeclareFields()的效果:");
for(Field field:fields2){
System.out.println("属性名:"+field.getName());
System.out.println("属性类型:"+field.getType());
System.out.println();
}
}
}
字节码对象.getMethods()。说明:得到该字节码对象对应类的所有方法。
package reflectTest;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @author:tengsen
* @create: 2022-10-09 12:07
* @Description:
*/
public class TestReflect3 {
public static void main(String[] args) throws ClassNotFoundException {
Class> cla = Class.forName("reflectTest.Student");
Method[] methods = cla.getMethods();//获取字节码对象对应类的所有方法,存于数组集合中
for (Method method: methods){
System.out.println("该方法对象详情为:");
System.out.println(method);
System.out.print("方法名为:");
System.out.println(method.getName());
Class>[] parameterTypes = method.getParameterTypes();//获取该方法的所有参数类型的数组集合
System.out.print("该方法的参数类型的数组集合为:");
System.out.println(Arrays.toString(parameterTypes));
System.out.println();
}
}
}
1>字节码对象.newInstance()。说明:执行无参构造创建对象。
2>字节码对象.newInstance(实参列表)。说明:执行有参构造创建对象。
package reflectTest;
import java.lang.reflect.Constructor;
/**
* @author:tengsen
* @create: 2022-10-09 14:47
* @Description:
*/
public class TestReflect4 {
public static void main(String[] args) throws Exception {
Class> cla = Class.forName("reflectTest.Student");
//如果已知构造器参数类型构成,可直接通过字节码对象获取对应构造器
Constructor> cons = cla.getConstructor(String.class,String.class,int.class,String.class);
//有参构造
Student student1 = (Student) cons.newInstance("006","古草",21,"男");
System.out.println(student1);
//通过字节码对象,直接反射获取无参构造的类实例
Student student2 = (Student) cla.newInstance();
System.out.println(student2);
}
}
1>字节码对象.getPackage().getName()。说明:获取包名。
2>字节码对象.getName()。说明:获取完整类名。
3>字节码对象.getSimpleName()。说明:获取类名。
package reflectTest;
/**
* @author:tengsen
* @create: 2022-10-09 15:01
* @Description:
*/
public class TestReflect5 {
public static void main(String[] args) throws ClassNotFoundException {
Class cla = Class.forName("reflectTest.Student");
//获取包名
System.out.println("Student类的包名:"+cla.getPackage());
//获取完整类名
System.out.println("Student类的完整类名:"+cla.getName());
//获取简洁类名
System.out.println("Student类的简洁类名:"+cla.getSimpleName());
}
}