开发者学堂课程【Java 高级编程:反射调用成员】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/20/detail/383
反射调用成员
内容简介:
一、获取成员
二、修改要操作的父类结构
三、获取类中的成员
四、直接调用 person 类中的 name 私有成员
五、获取 person 类中的 name 成员类型
一、获取成员
类结构之中的最后一个核心的组成就是成员 field,大部分情况下都会将其称为成员属性。对于成员信息的获取也是通过 class类完成的,在这个类中提供有如下两组操作方法
1. 获取本类全部成员
Public Filedp[] getDexlaredFields()
Throws SecurityException
2. 获取本类指定成员
public Field getDeclaredField(String name)
|throws NoSuchFieldException,
SecurityException
3. 获取父类全部成员;
public Field[] getFields()
throws SecurityException
4. 获取父类指定成员;
public Field getField(String name) I
throws NoSuchFieldException,
SecurityException
二、修改要操作的父类结构
package cn.mldn.abs;
bublic abstract iNlass AbstractBase {protected static final String BASE ="www.mldn.cn";
private String info = "Hello MLDN" ;public AbstractBase() {}
public AbstractBase(String msg) {}
}
package cn.mldn.service;
public interface IChannelService {
public static final String NAME = "mldnjava" ;public boolean connect() ;
}
在 person 类中,也有自己的成员属性。
三、获取类中的成员
Filed 类是 accessibleobject 的子类,在最早的版本中,三个类都属于accessibleobject 的子类。
这是在进行反射处理过程中最核心的图。
第一组操作取得父类信息。
插入分割线。
第二组操作获取子类中的定义的成员。
总体代码如下。
package cn.mldn.demo;
import java.lang.reflect.Field;
public class JavaAPIDemo {
public static void main(String[] args) throws Exception {
Class<?>c1s =lass.forNome("cn.mldn.vo.Person");
Field fields [] = cls.getiields();// g ”
for (Field fie: fields)(
system.out.println(fie);
}
System.out.println("--番茄酱分割线);
Field fields = cls.getDeclaredFields(DFields();//RmRM
for (Field fie : fields) (
System.out.println(fie);
}
}
}
对于 declared 操作,成员越往底,描述的越细。构造方法时,这个操作并不明显。
但是在 filed 类里面最为重要的操作形式并不是获取全部的成员,像之前见到的获取全部成员的数据的操作,并不是最终所需要的处理形式,而是如下的三个方法
public void set(Object obj,
Object value)
throws IllegalArgumentException,
IllegalAccessException
设置属性内容
public Object get(Object obj)
throws IllegalArgumentException,
IllegalAccessException
获取属性内容
这两个操作之中,都要求传递实例化对象。所有的成员是在对象实例化之后进行空间分配的,所以此时一定要先有实例化对象之后,才可以进行成员的操作。
四、直接调用 person 类中的 name 私有成员
先获取成员对象,接着实例化对象,这样才能分配成员空间。因为追加了 private,所以不能直接调用。因为属性私有之后就不能执行了。所以存在一个重要方法及解除封装
Public void setAccessible(blooean flag)
叫做 setaccessible
这句话来自于 accessibleobject。证明不仅仅是成员可以解除,构造也可以解除封装,方法也能解除封装。代码如下
package cn.mldn.demo;
import java.lang.reflect.Field;
public class JavaAPIDemo {
public static void main(String[] args)throws Exception {
Class<?>cls = Class.forName("cn.mldn.vo.Person");
0bject obj= cls.getconstructor().newInstance();
Field nameField= cls.getDeclaredField("name"); nameField.setAccessible(true);
nameField.set(obj,“番茄酱”);
System.out.println(nameField.get(obj));
}
}
此时完成成员调用
通过一系列的分析可以发现,类之中的构造,方法,成员属性都可以通过反射实现调用,但是对于成员的反射调用很少这样直接处理,大部分操作都应该通过 setter 和getter 处理,所以以上的代码只能够说是反射的特色,但是不具备有实际的使用能力,而对于 filed 类在实际开发之中只有一个方法最为常用
获取成员类型
Public publicClass<?> getType()
五、获取 person 类中的 name 成员类型
package cn.mldn.demo;
import java.lang.reflect.Field;
public class JavaAPIDemo {
public static void main(StringlNargs) throws Exception {
Class<?> cls e Class.forName("cn.mldn.vo.Person");
Field nameField = cls.getDeclaredField("name");
System.out.println(nameField.getType().getName());
System.out.println(nameField.getType().getSimpleName());
用 getsimplename 得到的是类名本身,而 name 是获取完整类名称''包.类''。
在以后开发中进行反射处理的时候,往往会利用 filed 与 method 类实现类中的setter 方法的调用。