字节码信息
创建类和接口
public interface MyInterface {
void myMethod();
}
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();// 属性
}
public class Person implements MyInterface{
// 属性
private String name;
private int age;
// 方法
public void eat() {
System.out.println("person-------eat");
}
public void sleep() {
System.out.println("person------sleep");
}
public void myMethod() {
System.out.println("person-------myMethod");
}
}
@MyAnnotation("student")
public class Student extends Person implements Serializable {
// 属性
private int sno;
double height;
protected double weight;
public double score;
// 方法
public String showInfo() {
return "我是一名三好学生";
}
// 方法
public String showInfo(int sno) {
return "我是一名三好学生";
}
private void work() {
System.out.println("我以后会找工作----成为一个程序员");
}
private void work(double score) {
System.out.println("我以后会找工作----成为一个程序员");
}
// 构造器
public Student() {
System.out.println("空参构造器");
}
private Student(int sno) {
System.out.println("一个参数的构造器");
this.sno = sno;
}
public Student(double height, double weight) {
System.out.println("两个参数的构造器");
this.height = height;
this.weight = weight;
}
Student(int sno, double weight) {
System.out.println("两个参数的构造器");
this.sno = sno;
this.weight = weight;
}
@Override
@MyAnnotation("hellomyMethod")
public void myMethod() throws RuntimeException{
System.out.println("重写了父类方法");
}
@Override
public String toString() {
return "Student{" +
"sno=" + sno +
", height=" + height +
", weight=" + weight +
", score=" + score +
'}';
}
}
获取字节码信息的四种方式
/**
* 获取字节码信息的四种方式
* 方式1 和 方式2 不常用
* 方式3 用的最多
* 方式4 了解
*/
public class TestClassInfo {
// 方式1 通过 getClass() 方法获取
@Test
public void test01() {
Person person = new Person();
Class<? extends Person> clazz = person.getClass();
System.out.println("clazz = " + clazz);
}
// 方式2 通过内置class属性
@Test
public void test02() {
Class<Person> person = Person.class;
System.out.println("person = " + person);
}
// 方式3 调用Class类提供的静态方法forName()
@Test
public void test03() throws ClassNotFoundException {
Class<?> clazz = Class.forName("com.maliqiang.demo.Person");
System.out.println("clazz = " + clazz);
}
// 方式4 利用类加载器(了解)
@Test
public void test04() throws ClassNotFoundException {
ClassLoader classLoader = TestClassInfo.class.getClassLoader();
Class<?> loadClass = classLoader.loadClass("com.maliqiang.demo.Person");
System.out.println("loadClass = " + loadClass);
}
}
反射测试
获取构造器和创建对象
// 获取构造器和创建对象
@Test
public void test01() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 获取字节码信息
Class<Student> sClazz = Student.class;
// 通过字节码信息可以获取 运行时 public修饰的构造器
Constructor<?>[] sClazzConstructors = sClazz.getConstructors();
for (Constructor<?> sClazzConstructor : sClazzConstructors) {
System.out.println("sClazzConstructor = " + sClazzConstructor);
}
System.out.println("===================================================");
// 通过字节码信息 获取运行时 所有构造器
Constructor<?>[] sClazzDeclaredConstructors = sClazz.getDeclaredConstructors();
for (Constructor<?> sClazzDeclaredConstructor : sClazzDeclaredConstructors) {
System.out.println("sClazzDeclaredConstructor = " + sClazzDeclaredConstructor);
}
System.out.println("------------------------------------------------------");
// 获取指定构造器 空参构造器
Constructor<Student> sClazzConstructor = sClazz.getConstructor();
System.out.println("sClazzConstructor = " + sClazzConstructor);
System.out.println("------------------------------------------------------");
// 得到两个参数的有参构造器 public
Constructor<Student> studentConstructor = sClazz.getConstructor(double.class, double.class);
System.out.println("studentConstructor = " + studentConstructor);
// default
Constructor<Student> sClazzDeclaredConstructor = sClazz.getDeclaredConstructor(int.class, double.class);
System.out.println("sClazzDeclaredConstructor = " + sClazzDeclaredConstructor);
System.out.println("------------------------------------------------------");
// 得到1个参数的有参构造器 并且是private修饰的
Constructor<Student> studentConstructor2 = sClazz.getDeclaredConstructor(int.class);
System.out.println("studentConstructor2 = " + studentConstructor2);
// 有了构造器 可以通过构造器 创建对象
Student student = sClazzConstructor.newInstance();
System.out.println("student = " + student);
Student student1 = studentConstructor.newInstance(110.0, 120.9);
System.out.println("student1 = " + student1);
// 不是public修饰的构造器 设置 setAccessible(true)
sClazzDeclaredConstructor.setAccessible(true);
Student student2 = sClazzDeclaredConstructor.newInstance(10, 120.9);
System.out.println("student2 = " + student2);
}
获取属性和对属性进行赋值
// 获取属性 和 对属性赋值
@Test
public void test02() throws NoSuchFieldException, IllegalAccessException, InstantiationException {
// 获取运行时 类的字节码信息
Class<Student> studentClass = Student.class;
// 获取属性
// getFields() 获取运行时 类和父类中被public修饰的属性
Field[] fields = studentClass.getFields();
for (Field field : fields) {
System.out.println("field = " + field);
}
System.out.println("-----------------------------------");
// 获取运行时类中的所有属性
Field[] declaredFields = studentClass.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println("field = " + field);
}
System.out.println("-----------------------------");
//获取指定的属性 public 修饰
Field score = studentClass.getField("score");
System.out.println("score = " + score);
//获取指定的属性
Field sno = studentClass.getDeclaredField("sno");
System.out.println("sno = " + sno);
// 获取修饰符
int modifiers = sno.getModifiers();
System.out.println("modifiers = " + Modifier.toString(modifiers));
// 获取属性的数据类型
Class<?> snoType = sno.getType();
System.out.println("snoType = " + snoType);
// 获取属性的名字
String snoName = sno.getName();
System.out.println("snoName = " + snoName);
// 给属性赋值
Student student = studentClass.newInstance();
// 反射 给public以外的属性赋值 要设置 setAccessible(true)
sno.setAccessible(true);
sno.set(student, 10);
System.out.println("student = " + student);
}
获取方法和调用方法
// 获取方法和调用方法
@Test
public void test03() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
// 获取字节码信息
Class<Student> sc = Student.class;
// 获取被public修饰的方法
Method[] methods = sc.getMethods();
for (Method method : methods) {
System.out.println("method = " + method);
}
System.out.println("============================================");
// 获取所有的方法
Method[] declaredMethods = sc.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println("declaredMethod = " + declaredMethod);
}
// 获取指定方法 public 修饰
Method showInfo = sc.getMethod("showInfo");
System.out.println("showInfo = " + showInfo);
Method showInfo1 = sc.getMethod("showInfo", int.class);
System.out.println("showInfo1 = " + showInfo1);
// 获取指定方法
Method work = sc.getDeclaredMethod("work");
System.out.println("work = " + work);
Method work1 = sc.getDeclaredMethod("work", double.class);
System.out.println("work1 = " + work1);
/// 获取方法的具体结构:
/*
@注解
修饰符 返回值类型 方法名(参数列表) throws XXXXX{}
*/
// 名字
System.out.println("work.getName() = " + work.getName());
//修饰符
System.out.println("work.getModifiers() = " + Modifier.toString(work.getModifiers()));
// 返回值
Class<?> returnType = work.getReturnType();
System.out.println("returnType = " + returnType);
// 参数列表
Class<?>[] parameterTypes = work1.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
System.out.println("parameterType = " + parameterType);
}
// 获取注解
Method myMethod = sc.getMethod("myMethod");
Annotation[] annotations = myMethod.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println("annotation = " + annotation);
}
// 获取异常
Class<?>[] exceptionTypes = myMethod.getExceptionTypes();
for (Class<?> exceptionType : exceptionTypes) {
System.out.println("exceptionType = " + exceptionType);
}
// 调用方法
work.setAccessible(true);
work.invoke(sc.newInstance());
}
获取类的接口,所在包,注解
// 获取类的接口,所在包,注解
@Test
public void test04() {
// 获取字节码信息
Class<Student> sc = Student.class;
// 获取运行时类的接口
Class<?>[] interfaces = sc.getInterfaces();
for (Class<?> anInterface : interfaces) {
System.out.println(anInterface);
}
// 得到父类的接口 先要得到父类的字节码信息
Class<? super Student> superclass = sc.getSuperclass();
Class<?>[] interfaces1 = superclass.getInterfaces();
for (Class<?> aClass : interfaces1) {
System.out.println("aClass = " + aClass);
}
// 获取运行时 类所在的包
Package aPackage = sc.getPackage();
System.out.println("aPackage = " + aPackage);
System.out.println("aPackage.getName() = " + aPackage.getName());
// 获取运行类的注解
Annotation[] annotations = sc.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println("annotation = " + annotation);
}
}