通过该部分的介绍,你会对“封装性”产生怀疑,因为通过反射可以毫无压力的破坏掉这些所谓的封装。
类中的属性必须在本类实例化对象产生产生之后才会分配内存空间,在Class类中存在取得成员的方法,
一是取得全部成员:public Field[] getDeclaredFields()
二是取得指定成员:public Field getDeclaredField(String name)
可以看出,它们的返回值类型都是和Field相关的,观察这个类,其属于java.lang.reflect.Field,该类有两个重要的方法:
1、public Object get(Object obj) 获取此 Field 表示的字段的值
public void set(Object obj, Object value)
2、
`我们可以定义一个类,这个类中存在私有属性,那么在正常情况下,是不可以在类外访问这个属性的,但是可以通过反射来获取该属性。
示例:
package com.andy.entity;
public class Cat {
private int age;//定义猫的年龄
private double weight;//定义猫的体重
public Cat(int age,double weight)
{
this.age=age;
this.weight=weight;
}
public Cat() {
System.out.println("-----这是无参构造函数-----------");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
@Override
public String toString() {
return "猫的年龄是"+age+" 体重是"+weight;
}
}
现在在另外一个类中通过反射获取该类的属性,并设置值。
代码如下:
package com.andy.temp;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Temp {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
String fildName1="age";
String fildName2="weight";
Class<?>class1=Class.forName("com.andy.entity.Cat");
try {
Constructor<?> constructor=class1.getConstructor(int.class,double.class);
Object cat=constructor.newInstance(2,2.6);//相当于正常情况下的new,会调用构造函数
Field ageFiled=class1.getDeclaredField("age");//相当于cat.age
ageFiled.setAccessible(true);//先取消封装
ageFiled.set(cat, 6);
Field weightField=class1.getDeclaredField("weight");
weightField.setAccessible(true);
weightField.set(cat, 3.6);
System.out.println(cat);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String initcap(String str) {
return str.substring(0,1).toUpperCase()+str.substring(1).toLowerCase();
}
}
在java.lang.reflect.Field的上层是继承了java.lang.reflect.AccessibleObject的,在AccessibleObject类中有一个可以取消封装的方法,名为setAccessible,
定义为public void setAccessible(boolean flag),将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
值为 false 则指示反射的对象应该实施 Java 语言访问检查。 注意:这个操作应该在逻辑操作之前进行,否则不成功。