一、反射
对于任意一个类,都能知道这个类的所有属性和方法
对于任意一个对象,都能够调用它的任意一个方法和属性
这种动态获取的信息以及动态调用对象方法的功能称之为java语言的反射机制
举例
后宫中有A贵妃、B贵妃。A比B漂亮,B很嫉妒。B用A的头发做小人,用针扎。此时A会感觉到疼痛。
我们操作的是小人,但实际上反射的是A。A是一个对象,B是调用者,小人是A的映射对象(Class)
二、获取Class对象
1、通过class.forName()来获取Class对象
Class clazz = Class.forName("一个类的完全限定名");
2、通过类名.class来获取
Class clazz = Emp.class;
3、通过对象的getClass()方法来获取
Class clazz = new Emp().getClass();
三、ClassAPI
1、获取成员变量,包括子类及父类,同时只能包含公共的方法(不推荐)
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
System.out.println(field.getName());
System.out.println(field.getType());
System.out.println(field.getModifiers());
}
2、获取成员变量,返回当前类的所有属性,所有的访问修饰符都可以拿到(推荐)
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField.getName());
}
3、反射在一定意义上破坏了封装性,需要合理使用
A类中有属性:private String address;
主方法中:
Field address = clazz.getDeclaredField("address");
//设置该属性是否能被访问,true表示能被访问,破坏了封装性
address.setAccessible(true);
System.out.println(address.getName());
Object o = clazz.newInstance();
address.set(o,"北京市");
System.out.println(((Student)o).getAddress());
4、获取该对象的普通方法,会包含的方法范围是当前对象及父类对象的所有公共方法
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
5、获取当前类中所有的方法,无论什么访问修饰符
Method[] declaredMethods = clazz.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod.getName());
}
Method add = clazz.getDeclaredMethod("add", int.class, int.class);
add.setAccessible(true);
Object o1 = clazz.newInstance();
add.invoke(o1,123,123);
6、获取对象的所有的构造方法,只能获取公共的构造方法
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println(constructor.getName());
}
7、获取所有的构造方法,无论是公有还是私有
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor.getName());
}
8、获取私有的构造方法
Constructor<?> declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class, String.class);
declaredConstructor.setAccessible(true);
Student o2 = (Student)declaredConstructor.newInstance("msb", 23, "java");
System.out.println(o2);