反射
概念
JAVA程序在运行状态时,能够获取任意一个类的属性和方法;
并且可以创建类的对象实例,调用它的任意属性和方法;
这种动态获取类的信息以及动态调用对象方法的功能称为java的反射机制。
获取Class对象
每个类被系统加载后,系统会为该类生成一个对应的Class对象,通过它可以访问到JAVA虚拟机中的这个类。
我们可以通过三种方式来获取Class的对象
1)通过某个类的class属性
2)通过Class类的forName(String className)静态方法,className为全限定名,比如String的全限定名为java.lang.String
3)通过对象调用Object的getClass()方法
1 package com.java.reflect; 2 3 4 import com.java.model.Student; 5 6 public class ReflectTest { 7 public static void main(String[] args) throws ClassNotFoundException { 8 //1.通过某个类的class属性 9 Class<Student> stu1 = Student.class; 10 System.out.println(stu1); 11 12 //2.通过Class类的forName(String className)静态方法 13 Class<Student> stu2 = (Class<Student>)Class.forName("com.java.model.Student"); 14 System.out.println(stu2); 15 16 //3.通过对象调用Object的getClass()方法 17 Class stu3 = new Student().getClass(); 18 System.out.println(stu3); 19 20 System.out.println((stu1 == stu2) && (stu2 == stu3) && (stu1 == stu3)); //true 21 } 22 }
获取类的信息
package com.java.reflect; import com.java.model.Student; public class ReflectTest { public static void main(String[] args) throws ClassNotFoundException { //1.通过某个类的class属性 Class<Student> stu = Student.class; System.out.println("1: " + stu); //2.得到包名 System.out.println("2: " + stu.getPackage()); //3.得到类的全限定名 System.out.println("3: " + stu.getName()); //4.得到类的简称 System.out.println("4: " + stu.getSimpleName()); //5.得到父类,返回表示此Class所表示的实体的超类的Class System.out.println("5: " + stu.getSuperclass().getSimpleName()); //6.得到接口 System.out.println("6: " + stu.getInterfaces()); System.out.println(" Interfaces:"); Class[] interfArr = stu.getInterfaces(); for(Class interf : interfArr){ System.out.println(" " + interf); } } }
获取构造函数、方法和字段
1 package com.java.reflect; 2 3 4 import java.lang.reflect.Constructor; 5 import java.lang.reflect.Field; 6 import java.lang.reflect.Method; 7 8 import com.java.model.Student; 9 10 public class ReflectTest { 11 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, NoSuchFieldException { 12 System.out.println("1.通过某个类的class属性"); 13 Class<Student> stu = Student.class; 14 System.out.println(stu); 15 16 System.out.println("2.获取public修饰的构造器函数"); 17 Constructor[] cons = stu.getConstructors(); 18 for(Constructor con : cons){ 19 System.out.println(con); 20 } 21 22 System.out.println("3.获取指定的public修饰的构造器函数"); 23 Constructor con = stu.getConstructor(String.class); 24 System.out.println(con); 25 26 System.out.println("4.获取全部的构造器函数"); 27 Constructor[] cons2 = stu.getDeclaredConstructors(); 28 for(Constructor con2 : cons2){ 29 System.out.println(con2); 30 } 31 32 System.out.println("5.获取包含父类的public修饰的方法"); 33 Method[] methods = stu.getMethods(); 34 for(Method method : methods){ 35 System.out.println(method); 36 } 37 38 System.out.println("6.获取指定的public方法"); 39 Method method2 = stu.getMethod("sayName", null); 40 System.out.println(method2); 41 42 System.out.println("7.获取类的所有方法,但是不能获取继承的方法和它实现接口的方法"); 43 Method[] methods2 = stu.getDeclaredMethods(); 44 for(Method meth : methods2){ 45 System.out.println(meth); 46 } 47 48 System.out.println("8.获取public修饰的字段"); 49 Field[] fs = stu.getFields(); 50 for(Field f : fs){ 51 System.out.println(f); 52 } 53 54 System.out.println("9.获取特定字段"); 55 Field f2 = stu.getField("name"); 56 System.out.println(f2); 57 58 System.out.println("10.获取不限定名称的全部字段,只对当前类有效"); 59 Field[] fields = stu.getDeclaredFields(); 60 for(Field field : fields){ 61 System.out.println(field); 62 } 63 } 64 }
getDeclaredMethod
私有方法直接访问会报错->setAccessible(true)
可以获取类的所有方法,但是不能获取继承的方法和它实现接口的方法
getMethod
只能获取public方法,但是可以获取继承的方法和它实现接口的方法
如何获取私有类型的field > getDeclaredField
如何获取类的构造函数
总结
反射就是把java中的各种成分映射成一个个的java对象,如Class,Method,Field