黑马程序员——java中的反射

来源:互联网 发布:情义知多少 编辑:程序博客网 时间:2024/03/29 04:46

------- android培训、java培训、期待与您交流! ----------

反射的基石是Class类,注意这里Class的是一个类,关键字的class首字母是小写的。java中的各个java类都属于同一类事物,描述这类事物的的类的类名就是Class。例如:众多的人可以用什么类来表示呢?答案是Person类。那么众多的java类可以用什么类来表示呢?答案是Class类。

下面来看一下如何获取字节码对应的实力对象呢(类型是Class),一共用三种方式。

两种方法分别如下所示:

第一种是通过:类名.class 例如Person.class

第二种就是:对象.getClass() 例如"a".getClass()

这里要着重说的是Class类的静态方法forName()方法,通过如下代码调用:

Class.forName("org.edu.Person");
如果类加载器曾经加载过这个类,那么这个静态方法返回的是Person类的字节码,如果没有,类加载器则加载这个类,并返回Person类的字节码。

这种方式还会产生异常,需要我们处理。在这三种方式中,第三种方式最常用。

一个java类的组成部分可能有成员变量,方法,构造方法等,这些都可以用一个个的类来表示,表示java类的Class类显然可以通过一系列的方法获取java类中的信息。反射就是把java类中的各种成分映射成相应的java类。

构造方法的反射应用:

//获取String类所有的构造方法

Constructor<?>[] constructors = Class.forName("java.lang.String").getConstructors();
//获取String类某一个构造方法</span>

Constructor<?> constructor = String.class.getConstructor(StringBuffer.class);

下面来一个小测试:我们来利用String类的一个构造方法来实例化一个String对象,代码如下:

Constructor constructor = String.class.getConstructor(StringBuffer.class);
String str = (String) constructor.newInstance(new StringBuffer("abc"));
字段的反射应用:

Field类代表某个类中的成员变量,如果想要访问一个类的私有成员变量,我们是可以做到的,代码如下:

Person p = new Person("kevin",23);Field fieldAge = p.getClass().getDeclaredField("age");
fieldAge.setAccessible(true);

System.out.println(fieldAge.get(p));
不得不提的是上面代码中的fieldAge对象代表的是类中的成员变量,它是与类相关联的,它代表的是age的定义,并不是具体age变量。

下面是一个小练习:将任意的一个对象中的String类型的成员变量所对应的字符串内容中的“b”替换为“a”。

Person p = new Person("ben",23);
Field[] fields = p.getClass().getFields();

for(Field field : fields){
<span style="white-space:pre"></span>if(field.getType() == String.class){
<span style="white-space:pre"></span>String oldValue = (String) field.get(p);
<span style="white-space:pre"></span>String newValue = oldValue.repalace("b","a");
<span style="white-space: pre;"></span>field.set(p,newValue);
}
接下来是成员方法的反射:

Method类代表某一个类中的成员方法。

Method m = String.class.getMethod("charAt",int.class);
String str = "abc";
m.invoke(str,1);

如果传递给Method对象的invoke方法的第一个参数为null,那么很明显说明调用的是静态方法。因为静态方法不需要实例化的对象。



0 0