反射
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
可以通过Class类取得类信息,通过Class类调用属性或方法
反射给开发者提供了可根据类信息动态生成对象并执行对象行为的一系列操作,这个特性让编写更加灵活的底层框架时尤为重要
代码演示:
先创建一个实体类:
public class Dog { public int type; private String name; private int age; private String sex; // ... }
获取Class对象的三种方式:
Dog dog = new Dog("haunhuan", 1, "公"); Class aClass = dog.getClass(); System.out.println(aClass); // 通过类.class Class dogClass = Dog.class; System.out.println(dogClass); //通过Class.forName方法 try { Class aClass1 = Class.forName("com.lili.reflect.Dog"); System.out.println(aClass1); } catch (ClassNotFoundException e) { e.printStackTrace(); } }
通过反射来实例化对象:
Class<Dog> dogClass = Dog.class; try { // 通过Class对象实例化类对象,调用了默认无参的构造方法 Dog dog = dogClass.newInstance(); } catch (InstantiationException | IllegalAccessException e) { e.printStackTrace(); }
获取所有的构造方法:
Class<Dog> dogClass = Dog.class; Constructor[] constructors = dogClass.getConstructors(); for (Constructor value : constructors) { System.out.println(value.getName()); // 构造器的个数 System.out.println(value.getParameterCount()); } try { // 获取一个指定的构造方法 Constructor<Dog> constructor = dogClass.getConstructor(String.class, int.class, String.class); // 调用一个有参数的来实例化对象 Dog dog = constructor.newInstance("小白", 5, "母"); } catch (NoSuchMethodException | InvocationTargetException | InstantiationException | IllegalAccessException e) { e.printStackTrace(); } }
获取所有属性:
Class<Dog> dogClass = Dog.class; // 获取非私有属性 Field[] fields = dogClass.getFields(); System.out.println(fields.length); // 获取所有属性(包括私有属性) Field[] declaredFields = dogClass.getDeclaredFields(); System.out.println(declaredFields.length); for (Field declaredField : declaredFields) { int modifiers = declaredField.getModifiers(); System.out.println(Modifier.toString(modifiers) + "" + declaredField.getType() + "" + declaredField.getName()); }
获取类的包名:
Package aPackage = dogClass.getPackage();
获取公共的方法,包括继承的方法
Method[] methods = dogClass.getMethods(); for (Method method : methods) { System.out.println(method); if ("toString".equals(method.getName())) { try { String s = (String) method.invoke(dog); System.out.println(s); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } }
访问私有方法,获取到本类的所有方法
Method[] declaredMethods = dogClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { System.out.println(declaredMethod); if ("set".equals(declaredMethod.getName())) { //设置私有方法可以被访问(去除访问修饰符的检查) declaredMethod.setAccessible(true); try { declaredMethod.invoke(dog); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } } }