一. 反射的由来
编译阶段:将java文件编译成字节码文件。
加载过程:通过类加载器,在方法区中加载类的静态属性和静态方法,在堆中存放该类的反射类对象。
运行过程:执行方法。
二. 反射的用法
首先创建Dog类
public class Dog { public String name; public int age; public String color; public Dog(){} public Dog(String name, Integer age, String color) { this.name = name; this.age = age; this.color = color; } public void run(){ System.out.println(name + "在跑步"); } public void sleep(){ System.out.println(name + "在睡觉"); } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + ", color='" + color + '\'' + '}'; } }
反射对象的方法使用
public class Reflection03 { public static void main(String[] args) throws Exception{ Class<?> aClass = Class.forName("com.hspedu.Dog"); // class com.hspedu.Dog aClass引用指向的是Dog类的Class【反射对象】 System.out.println(aClass); // class java.lang.Class aClass对象的运行类型Class【反射类】 System.out.println(aClass.getClass()); // 1.获取类的路径 String name = aClass.getName(); System.out.println(name); // 2.获取包名 Package aPackage = aClass.getPackage(); System.out.println(aPackage); // 3.1 获取无参构造器 // public com.hspedu.Dog() Constructor<?> constructor1 = aClass.getConstructor(); System.out.println(constructor1); // 3.2 获取带参构造器 // public com.hspedu.Dog(java.lang.String,java.lang.Integer,java.lang.String) Constructor<?> constructor2 = aClass.getConstructor(String.class, Integer.class, String.class); System.out.println(constructor2); // 4 获取对象【无参】 Object o = aClass.newInstance(); // com.hspedu.Dog System.out.println(o.getClass()); // 5.设置属性 Field dogName = aClass.getField("name"); dogName.set(o,"Tom"); Field age = aClass.getField("age"); age.set(o,8); Field color = aClass.getField("color"); color.set(o,"白色"); System.out.println(o); // 6.调用方法 Method run = aClass.getMethod("run"); run.invoke(o); Method sleep = aClass.getMethod("sleep"); sleep.invoke(o); // 7.一次性得到反射对象的属性 Field[] fields = aClass.getFields(); for (Field field : fields) { System.out.println(field.getName()); } } }
三. 获取反射对象
public class Reflection04 { public static void main(String[] args) throws Exception{ // 获取反射对象 // 方式1:编译阶段,通过Class.forName(类的路径) Class<?> aClass = Class.forName("com.hspedu.Dog"); System.out.println(aClass.hashCode()); // 方式2:加载阶段,类名.class Class<Dog> dogClass = Dog.class; System.out.println(dogClass.hashCode()); // 方式3:类加载器 Class<?> aClass1 = ClassLoader.getSystemClassLoader().loadClass("com.hspedu.Dog"); System.out.println(aClass1.hashCode()); // 方式4:基本数据类型.class Class<Integer> integerClass = int.class; System.out.println(integerClass.hashCode()); // 方式5:包装类.TYPE Class<Integer> type = Integer.TYPE; System.out.println(type.hashCode()); } }
运行结果:
1554874502 1554874502 1554874502 1846274136 1846274136
说明同一个类的反射对象只有一个。
四. 类加载解读
1. 静态加载和动态加载
加载包括:静态加载和动态加载 静态加载:在编译阶段,加载所有的类,遇到没有import导入的类,编译异常; 动态加载:在运行阶段,加载所需要的类,如果没有,不出现编译异常,但是肯定有运行异常。 动态加载:反射【五种方式】; 静态加载:new ;调用静态成员;子类被加载时,父类也被加载。2. 类加载的具体过程
类加载图解:
这里的初始化,是静态成员的初始化,静态成员随着类的加载而加载。
类加载三个阶段的主要任务:
五.综合案例,获取类的结构信息
public class Reflection06 { public static void main(String[] args) throws Exception{ Class<?> aClass = Class.forName("com.hspedu.Student"); // 1.获取本类及其父类的public修饰的属性 Field[] fields = aClass.getFields(); for (Field field : fields) { System.out.println("本类及其父类的public修饰的属性: " + field.getName()); } // 2.获取父类的public修饰的属性 Class<?> superclass3 = aClass.getSuperclass(); Field[] fields1 = superclass3.getFields(); for (Field field : fields1) { System.out.println("父类的public修饰的属性: "+field.getName()); } // 3.获取本类中的所有属性 Field[] declaredFields1 = aClass.getDeclaredFields(); for (Field declaredField : declaredFields1) { System.out.println("本类的所有属性: " + declaredField.getName()); } // 4.获取父类的所有属性 Class<?> superclass = aClass.getSuperclass(); Field[] declaredFields2 = superclass.getDeclaredFields(); for (Field field : declaredFields2) { System.out.println("父类的所有属性: " + field.getName()); } // 5.获取本类以及父类的public修饰的方法 Method[] methods = aClass.getMethods(); for (Method method : methods) { System.out.println("本类以及父类的public修饰的方法: " + method.getName()); } // 6.获取父类的public修饰的方法 Class<?> superclass1 = aClass.getSuperclass(); Method[] methods1 = superclass1.getMethods(); for (Method method : methods1) { System.out.println("父类的public修饰的方法: " + method.getName()); } // 7.获取本类的所有方法 Method[] declaredMethods = aClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println("本类的所有方法: " + declaredMethod.getName()); } // 8.获取父类的所有方法 Class<?> superclass2 = aClass.getSuperclass(); Method[] declaredMethods1 = superclass1.getDeclaredMethods(); for (Method method : declaredMethods1) { System.out.println("父类的所有方法: " + method.getName()); } // 9.获取本类的public修饰的无参构造器 Constructor<?>[] constructors = aClass.getConstructors(); for (Constructor<?> constructor : constructors) { System.out.println("本类的public修饰的无参构造器: " + constructor.getName()); } // 获取本类指定的带参构造器 Constructor<?> constructor1 = aClass.getConstructor(String.class, String.class); System.out.println(constructor1); // 10.获取父类的public修饰的无参构造器 Class<?> superclass4 = aClass.getSuperclass(); Constructor<?>[] constructors1 = superclass4.getConstructors(); for (Constructor<?> constructor : constructors1) { System.out.println("父类的public修饰的无参构造器: " + constructor.getName()); } // 获取父类指定的带参构造器 Constructor<?> constructor = superclass4.getConstructor(String.class, int.class); System.out.println(constructor); // 11.获取本类所有的构造器 Constructor<?>[] declaredConstructors = aClass.getDeclaredConstructors(); for (Constructor<?> declaredConstructor : declaredConstructors) { System.out.println(declaredConstructor); } // 12.获取父类的所有构造器 Class<?> superclass5 = aClass.getSuperclass(); Constructor<?>[] declaredConstructors1 = superclass5.getDeclaredConstructors(); for (Constructor<?> constructor2 : declaredConstructors1) { System.out.println(constructor2); } // 13.获取本类的实现的接口 Class<?>[] interfaces = aClass.getInterfaces(); for (Class<?> anInterface : interfaces) { System.out.println(anInterface); } } } interface i1 { } interface i2 { } class Person { private String name; int age; protected String nation; public String gender; public Person() {} public Person(String name,int age){ this.name = name; this.age = age; } private Person(String name, String nation) { this.name = name; this.nation = nation; } public void p1(){ } protected void p2(){ } void p3(){ } private void p4(){ } } class Student extends Person implements i1,i2{ private String stuId; String hobby; protected String job; public int height; public Student(){} public Student(String stuId,String hobby){ this.stuId = stuId; this.hobby = hobby; } private Student(String stuId,int height){ this.height = height; this.stuId = stuId; } public void s1(){ } protected void s2(){ } void s3(){ } private void s4(){ } }
运行结果:
本类及其父类的public修饰的属性: height 本类及其父类的public修饰的属性: gender 父类的public修饰的属性: gender 本类的所有属性: stuId 本类的所有属性: hobby 本类的所有属性: job 本类的所有属性: height 父类的所有属性: name 父类的所有属性: age 父类的所有属性: nation 父类的所有属性: gender 本类以及父类的public修饰的方法: s1 本类以及父类的public修饰的方法: p1 本类以及父类的public修饰的方法: wait 本类以及父类的public修饰的方法: wait 本类以及父类的public修饰的方法: wait 本类以及父类的public修饰的方法: equals 本类以及父类的public修饰的方法: toString 本类以及父类的public修饰的方法: hashCode 本类以及父类的public修饰的方法: getClass 本类以及父类的public修饰的方法: notify 本类以及父类的public修饰的方法: notifyAll 父类的public修饰的方法: p1 父类的public修饰的方法: wait 父类的public修饰的方法: wait 父类的public修饰的方法: wait 父类的public修饰的方法: equals 父类的public修饰的方法: toString 父类的public修饰的方法: hashCode 父类的public修饰的方法: getClass 父类的public修饰的方法: notify 父类的public修饰的方法: notifyAll 本类的所有方法: s4 本类的所有方法: s3 本类的所有方法: s1 本类的所有方法: s2 父类的所有方法: p4 父类的所有方法: p3 父类的所有方法: p1 父类的所有方法: p2 本类的public修饰的无参构造器: com.hspedu.Student 本类的public修饰的无参构造器: com.hspedu.Student public com.hspedu.Student(java.lang.String,java.lang.String) 父类的public修饰的无参构造器: com.hspedu.Person 父类的public修饰的无参构造器: com.hspedu.Person public com.hspedu.Person(java.lang.String,int) private com.hspedu.Student(java.lang.String,int) public com.hspedu.Student(java.lang.String,java.lang.String) public com.hspedu.Student() private com.hspedu.Person(java.lang.String,java.lang.String) public com.hspedu.Person(java.lang.String,int) public com.hspedu.Person() interface com.hspedu.i1 interface com.hspedu.i2View Code
标签:aClass,java,String,反射,println,修饰,父类,public From: https://www.cnblogs.com/zwgitOne123/p/17058019.html