反射机制6(调用成员变量)
类中的属性一定要在本类实例化对象产生之后才分配内存空间。在Class类里面有取得成员的方法。
取得全部成员:public Field[] getDeclaredFields() throws SecurityException
取得指定成员:public Field getDeclaredField(String name)
throws NoSuchFieldException,SecurityException
返回的类型是:java.lang.reflect.Field类,在这个类里面有两个重要的方法
取得属性内容:public Object get(Object obj)
throws IllegalArgumentException,
IllegalAccessException
设置属性内容:
public void set(Object obj,
Object value)
throws IllegalArgumentException,
IllegalAccessException
范例:现在提供有如下的类。
class Book{
private String title;
}
这个类里面只定义了一个私有属性,按照原始的做法,一定无法被外部所使用,但是现在我们可以通过反射调用。
并且在java.lang.reflect.AccessibleObject类下面(JDK1.8之后从3变为2子类)
Executable:下面继续继承了Constructor,Method
Field:提供public void setAccessible()设置是否封装。
package TestDemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
class Book{
private String title;
}
public class TestDemo{
public static void main(String[] args) throws Exception{
Class<?> cls=Class.forName("TestDemo.Book");
Object obj=cls.newInstance();//获取无参构造实例化对象 因为普通方法只能获取实例化对象调用
//要操作的成员
Field titlField=cls.getDeclaredField("title");
titlField.setAccessible(true);//封装取消了
titlField.set(obj, "Java Dep");//相当于Book类对象.title="Java Dep"
System.out.println(titlField.get(obj));//相当于直接输出Book类对象.title
}
}
这里直接调用了private修饰的成员变量,通过.setAccessible(true)取消了封装。
普通方法和构造方法同样可以取消封装,只不过很少这样去做,而且对于属性的访问建议还是使用setter,getter方法完成。
总结:
1.实例化对象的方式又增加了一种反射
2.对于简单Java类的定义又应该更加清晰了(包括为什么要有无参)
3.反射调用类结构只是一个开始