反射
Created At : 2024-05-25 11:42
Views 👀 :
JVM为每个加载的class创建了对应的Class实例,并在实例中保存了该class的所有信息(类名,包名,父类,接口,方法,字段等),因此只要获取了某个Class实例,就能通过这个实例获取对应的class的所有信息,这就是反射(Reflection)
获取一个class的Class实例的方法有
1 2 //直接通过class的静态变量class获取 Class clazz = String.class;
1 2 3 //通过实例变量的getClass()方法 String s = "n1ng" Class clazz = s.getClass();
1 2 //如果知道Class的完整类名,可以通过静态方法Class.forName()获取 Class clazz = Class.forName("java.lang.String");
对于一个Object实例,只要获取了Class就可以知道他的所有信息
getSuperclass(),获取父类
getInterfaces(),获取接口
访问字段
Field getField(name),根据字段名获取public的field
Field getDeclaredField(name),根据字段名获取private的field
Field[] getFields(),获取所有public的field(包括父类)
Field[] getDeclaredFields(),获取当前类的所有field(不包括父类)
调用方法
Method getMethod(name,Class),获取某个public的method(包括父类)
Method getDeclaredMethod(name,Class),获取当前类的Method(不包括父类)
Method[] getMethods(),获取所有public的Method(包括父类)
Method[] getDeclaredMethods(),获取当前类的所有Method(不包括父类)
使用反射调用方法时,仍然遵循多态原则,会调用实际类型的覆写方法
调用构造方法 通过反射来创建实例时可以用newInstance()方法(Person p = new Person.class.newInstance();),但是他只能调用public无参数的构造方法,使用Constructor对象则可以避免。Constructor对象包含一个构造方法的所有信息,可以创建一个实例
getConstructor(class)获取某个public的Constructor
getDeclaredConstructor(class),获取某个Constructor
getConstructors(),获取所有public的Constructor
getDeclaredConstructors(),获取所有的Constructor
1 2 3 4 5 6 //对于非public的Constructor需要setAccessible(true)设置允许访问 Constructor con = Int.class.getConstructor(int.class); Integer n = (Integer) con.newInstance(123) Constructor con1 = Int.class.getConstructor(String.class); Integer n1 = (Integer) con1.newInstance("123")
example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 public class Main { public static void main (String[] args) { printClassInfo("" .getClass()); printClassInfo(Runnable.class); printClassInfo(java.time.Month.class); printClassInfo(String[].class); printClassInfo(int .class); Object p = new Person ("n1ng" ); Class clazz = p.getClass(); Field f = clazz.getDeclaredField("name" ); f.setAccessible(true ); Object value = f.get(p); System.out.println(value); f.set(p,"n2ng" ); System.out.println(p.getName()); System.out.println(clazz.getMethod("getScore" ,String.class())); System.out.println(clazz.getMethod("getName" )); System.out.println(clazz.getDeclaredMethod("getGrade" ,int .class)); String s = "Hello World" Method m = String.class.getMethod("substring" ,int .class); String r = (String) m.invoke(s,6 ); Method m1 = Inter.class.getMethod("parseInt" ,String.class); Integer n = (Integer) m1.invoke(null ,"1111" ); Person p = new Person (); Method m2 = p.getClass().getDeclaredMethod("setName" ,String.class); m2.setAccessible(true ); m2.invoke(p,"n1ng" ); } static void printClassInfo (Class clazz) { System.out.println("Class name: " + clazz.getName()); System.out.println("Simple name: " + clazz.getSimpleName()); if (clazz.getPackage() != null ) { System.out.println("Package name: " + clazz.getPackage().getName()); } System.out.println("is interface: " + clazz.isInterface()); System.out.println("is enum: " + clazz.isEnum()); System.out.println("is array: " + clazz.isArray()); System.out.println("is primitive: " + clazz.isPrimitive()); } static void printFieldInfo (Class clazz) { System.out.println(clazz.getField("name" )); System.out.println(clazz.getDeclaredField("sex" )) } class Person { String name; private void setName (String name) { this .name = name; } } }
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 3049155267@qq.com