反射的学习笔记
二、反射
-
reflection(反射)
1.1、初识反射:
package com.lix.reflection; /** * * @author lix * 什么叫反射 */ public class Test extends Object { public static void main(String[] args) throws ClassNotFoundException { //通过反射获取类的Class对象 Class<?> c1 = Class.forName("com.lix.reflection.User"); System.out.println(c1); Class<?> c2 = Class.forName("com.lix.reflection.User"); Class<?> c3 = Class.forName("com.lix.reflection.User"); Class<?> c4 = Class.forName("com.lix.reflection.User"); /** * 一个类在内存中只有一个Class对象 * 一个类被加载后,类的整个结构都会封装在Class对象中 */ System.out.println(c2.hashCode()); System.out.println(c3.hashCode()); System.out.println(c4.hashCode()); } } /** * 实体类 * */ class User{ private String name; private int id; private int age; public User() { } public User(String name, int id, int age) { this.name = name; this.id = id; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
package com.lix.reflection; /** * @author lix */ public class Test01 { public static void main(String[] args) throws ClassNotFoundException { Person person = new Student(); System.out.println("这个人是:"+person.name); //方式一 :通过对象获得 Class c1 = person.getClass(); System.out.println(c1.hashCode()); //方式二:forName 获得 Class<?> c2 = Class.forName("com.lix.reflection.Student"); System.out.println(c2.hashCode()); //方式三:通过类名.class获得 Class<Student> c3 = Student.class; System.out.println(c3.hashCode()); //方式四: 基本内置类型的包装类都有一个Type属性 Class<Integer> c4 = Integer.TYPE; System.out.println(c4.hashCode()); //获得父类类型 Class c5 = c1.getSuperclass(); System.out.println(c5); } } class Person{ public String name; public Person() { } public Person(String name) { this.name = name; } @Override public String toString() { return super.toString(); } } class Student extends Person{ public Student() { this.name = "学生"; } } class Teacher extends Person{ public Teacher() { this.name = "老师"; } }
1.2、通过反射获取并了解类
package com.lix.reflection; import java.lang.annotation.ElementType; /** * @author lix * 所有类型的class */ @SuppressWarnings("all") public class Test03 { public static void main(String[] args) { Class<Object> c1 = Object.class; //类 Class<Comparable> c2 = Comparable.class;//接口 Class<String[]> c3 = String[].class;//一维数组 Class<int[][]> c4 = int[][].class;//二维数组 Class<Override> c5 = Override.class;//注解 Class<ElementType> c6 = ElementType.class;//枚举 Class<Integer> c7 = Integer.class;//基本数据类型 Class<Void> c8 = void.class;//void Class<Class> c9 = Class.class; //class System.out.println(c1); System.out.println(c2); System.out.println(c3); System.out.println(c4); System.out.println(c5); System.out.println(c6); System.out.println(c7); System.out.println(c8); System.out.println(c9); /** * 只要元素类型与维度一样,就是一个class */ int[] a = new int[10]; int[] b = new int[100]; System.out.println(a.getClass().hashCode()); System.out.println(b.getClass().hashCode()); } }
1.3 、从内存分析class
package com.lix; /** * @author lix */ public class Test04 { public static void main(String[] args) { A a = new A(); System.out.println(A.m); } /** * 1.加载到内存,会产生一个类对应的class对象 * 2.链接, 链接结束后 m = 0 * 3.初始化 <clinit></clinit>(){ System.out.println("A类静态代码块初始化"); m = 300 m = 100 最后得出 m=100 } */ } class A{ static { System.out.println("A类静态代码块初始化"); m = 300; } static int m = 100; public A() { System.out.println("A类的无参构造初始化"); } }
1.4、类的初始化
- 主动引用(一定会发生类的初始化)
- 被动引用(一定不会发生类的初始化)
package com.lix.reflection; /** * @author lix * 测试类什么时候hi被初始化 */ public class Test05 { static { System.out.println("main类被加载"); } public static void main(String[] args) throws ClassNotFoundException { //1.主动引用 // Son son = new Son(); // // //反射也会产生主动引用 // Class.forName("com.lix.reflection.Son"); //不会产生类的引用的方法 // System.out.println(Son.b); // Son[] array = new Son[5]; System.out.println(Son.N); } } class Father { static int b = 2; static { System.out.println("父类被加载"); } } class Son extends Father { static { System.out.println("子类被加载"); m = 300; } static int m = 100; static final int N =1; }
1.5、类加载器
1.5.1、类运行流程图:
1.5.2、通过反射获得类的运行时信息
package com.lix.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /** * @author lix * 获取类的信息 */ public class Test06 { @SuppressWarnings("all") public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { Class<?> c1 = Class.forName("com.lix.reflection.User"); //获得类的名字 System.out.println(c1.getName()); //获得类名+包名 System.out.println(c1.getSimpleName()); //获得类名 //获得类的属性 Field[] fields = c1.getFields();//只能找到public属性 Field[] fields1 = c1.getDeclaredFields();//能找到全部属性 for (Field field : fields1) { System.out.println(field); } //获得指定属性的值 Field name = c1.getDeclaredField("name"); System.out.println(name); //获得类的方法 System.out.println("=================="); Method[] m1 = c1.getMethods();//获得父类全部的public方法 for (Method method : m1) { System.out.println(method); } Method[] m2 = c1.getDeclaredMethods();//获得苯类的所有方法 for (Method method2 : m2) { System.out.println(method2); } System.out.println("=================================="); Method getName = c1.getMethod("getName", null); Method setName = c1.getMethod("setName", String.class); System.out.println(getName); System.out.println(setName); //获得指定的构造器 System.out.println("===================---------==========="); Constructor<?>[] constructors = c1.getConstructors(); for (Constructor<?> constructor : constructors) { System.out.println(constructor); } Constructor<?> constructor1 = c1.getConstructor(); System.out.println(constructor1); } }
1.5.3、通过反射动态的创建对象
package com.lix.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * @author lix * 通过反射动态的创建对象 */ @SuppressWarnings("all") public class Test07 { public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException { Class<?> c1 = Class.forName("com.lix.reflection.User"); //构造一个对象 User user = (User)c1.newInstance();//本质是调用了无参构造器 System.out.println(user); //通过构造器创建对象 Constructor<?> declaredConstructor = c1.getDeclaredConstructor(String.class, int.class, int.class); Object lix = declaredConstructor.newInstance("lix", 001, 20); System.out.println(lix); //通过反射调用普通方法 User user1 = (User)c1.newInstance(); //通过反射获取一个方法 Method setName = c1.getDeclaredMethod("setName", String.class); setName.invoke(user1,"lix"); System.out.println(user1.getName()); //通过反射操作属性 User user2 = (User)c1.newInstance(); Field name = c1.getDeclaredField("name"); //不能直接操作私有属性,需要关闭程序的安全检测,setAccessible name.setAccessible(true); name.set(user2,"ll"); System.out.println(user2.getName()); } }
本文来自博客园,作者:六爻呈乾,转载请注明原文链接:https://www.cnblogs.com/ilycq/p/13859714.html