在Java中,类是通过类加载器加载的。类加载器的任务是将Java字节码转换为在Java虚拟机中可以使用的运行时数据结构。以下是类加载器加载类的步骤:
是指在程序运行时,动态地获取类的信息、分析类的信息并操作对象的信息的能力。通过反射,可以在运行时获取类的成员变量、方法、构造函数等信息,还可以创建对象、调用方法、动态修改类的属性和方法等。
Class类是一个Java内置的类,用于描述其他类的结构和行为
因为没有构造方法,所以使用内部方法创建对象
方式一:
通过Object类中的getClass()方法
代码示例:
Class studentClass1 = student.getClass();
方式二:
通过 类名.class 获取到字节码文件对象
代码示例:
Class studentClass2=Student.class;
方式三:
通过Class类中的方法
代码示例:
try {
Class studentClass3=Class.forName("Class类的创建对象.Student");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
代码示例:
//获取Class对象
Class calss_studebt = Class.forName("通过反射获取构造方法并使用.Student");
//获取Claa对象的构造器(非私有)
Constructor constructor = calss_studebt.getConstructor(int.class, String.class);
System.out.println(constructor);
//调用构造器
Student student1 = (Student) constructor.newInstance(26, "sdasda");
System.out.println(student1.toString());
//获取Class对象的构造器(私有)
Constructor constructor1 = calss_studebt.getDeclaredConstructor();
System.out.println(constructor1);
//调用私有构造器,创建对象
Student student2 = (Student) constructor1.newInstance();
System.out.println(student2.toString());
代码示例:
//获取Class对象
Class class_student = Class.forName("获取成员变量进行赋值与获取值操作.Student");
//获取构造方法
Constructor constructor = class_student.getConstructor(int.class, String.class);
//创建对象
Student student = (Student)constructor.newInstance(20, "孙悟空");
System.out.println(student);
//获取成员变量(这里的成员变量为私有的)
Field field_name = class_student.getDeclaredField("name");
Field field_age = class_student.getDeclaredField("age");
//”修改“成员变量的权限(暴力破解)
field_age.setAccessible(true);field_name.setAccessible(true);
//取值
System.out.println(field_age.get(student));
System.out.println(field_name.get(student));
//赋值
field_age.set(student,25);
field_name.set(student,"猪八戒");
System.out.println(student);
代码示例:
.
//获取Class对象
Class class_student =Class.forName("通过反射获取成员方法并使用.Student");
//获取构造方法
Constructor<Student> constructor = class_student.getConstructor(int.class, String.class);
//创建对象
Student student = constructor.newInstance(28,"花蝴蝶");
//获取方法
Method method_getName = class_student.getMethod("getName");
System.out.println(method_getName);
Method method_setName = class_student.getMethod("setName",String.class);
System.out.println(method_setName);
//获取私有方法
Method method_getAge= class_student.getDeclaredMethod("getAge");
System.out.println(method_getAge);
Method method_setAge= class_student.getDeclaredMethod("setAge",int.class);
System.out.println(method_setAge);
//绑定方法给对象并使用
System.out.println(student);
method_setName.invoke(student,"沙和尚");
System.out.println(method_getName.invoke(student));
method_setAge.invoke(student,120);
System.out.println(method_getAge.invoke(student));
System.out.println(student);
结果展示:
这里的Student类是一个标准的JavaBean类,一些方法因为需要被设为私有
package 通过反射获取成员方法并使用;
class Student {
protected int age;
protected String name;
protected Student() {
}
protected int getAge() {
return age;
}
protected void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
public Student(int age, String name) {
this.age = age;
this.name = name;
}
}
泛型擦除
package 泛型擦除;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
//创建一个只能存Integer类型的数组
ArrayList<Integer> list = new ArrayList<>();
list.add(11);
list.add(13);
list.add(15);
//获取Class对象
Class<?> class_Arraylist = Class.forName("java.util.ArrayList");
//通过对象获取add方法,因为泛型值对编译起作用
Method class_add = class_Arraylist.getMethod("add",Object.class);
//这个时候就可以添加String类型的数据
class_add.invoke(list,"lllll");
System.out.println(list);
}
}