java反射筆記整理
一、反射基礎
1.Class對象的三種獲取方式
@Test
public void threeMethodForClassObj() throws ClassNotFoundException {
//1.每個類都有一個隱藏的靜態變量class
Class clazz1 = UserInfo.class;
//2.使用最多的獲取class的方式,只要知道全類名就可以獲取到,會拋ClassNotFountException
Class clazz2 = Class.forName("com.huangliwei.entity.UserInfo");
//3.對象繼承至Object的方法
UserInfo userInfo = new UserInfo();
Class clazz3 = userInfo.getClass();
log.debug("clazz1 [%s],clazz2[%s] 是否是同一個對象 %s", clazz1, clazz2, clazz1 == clazz2);
log.debug("clazz1 [%s],clazz3[%s] 是否是同一個對象 %s", clazz1, clazz3, clazz1 == clazz3);
//由此可見jvm中每個類只會有一個Class對象
}
2.獲取父類class對象
/**
* 獲取父類class對象,由於單一繼承特性,所以只會獲取到一個class對象
*/
@Test
public void getSupperClass(){
Class clazz = UserInfo.class;
Class superclass = clazz.getSuperclass();
log.debug("獲取父類class對象爲:%s",superclass.getName());
}
3.獲取實現的接口class對象
/**
* 獲取類實現的所有接口<由於接口可以多實現,所以獲取的接口爲一個數組
* 只能獲取到當前類實現的接口,不能獲取到父類實現的接口
*/
@Test
public void getInterfaces() {
Class clazz = UserInfo.class;
Class[] interfaces = clazz.getInterfaces();
for (Class interfaceClass : interfaces) {
log.debug("獲取實現的接口爲:%s", interfaceClass.getName());
}
}
二、反射常用對象
1.常用對象-Field
a.獲取Field的兩種方式對比
/**
* 根據class對象獲取類的成員變量
* @throws NoSuchFieldException
*/
@Test
public void getFields() throws NoSuchFieldException {
Class<UserInfo> clazz = UserInfo.class;
//獲取當前類的public修飾的所有成員變量,包括集成而來的
Field[] fields1 = clazz.getFields();
for (Field field : fields1) {
log.debug("獲取public 變量:%s", field.getName());
}
//獲取當前類所有的變量,private、protected、public……以及從父類繼承過來的public類型的變量
Field[] fields2 = clazz.getDeclaredFields();
for (Field field : fields2) {
log.debug("獲取當前類所有變量:%s", field.getName());
}
//還可以指定變量名獲取類的變量
Field idField = clazz.getField("id");
log.debug("指定名稱獲取public變量:%s", idField.getName());
Field usernameField = clazz.getDeclaredField("username");
log.debug("指定名稱獲取變量:%s", usernameField.getName());
}
b.遞歸獲取類的所有成員變量,包括父類所有成員變量
@Test
public void getAllFields() {
Map<String, List<Field>> map = new HashMap<>();
Class tempClass = UserInfo.class;
while (tempClass != null) {
//遞歸逐層獲取所有的類的私有變量
String className = tempClass.getName();
List<Field> fields = map.get(className);
fields = fields == null ? new ArrayList<Field>() : fields;
fields.addAll(Arrays.asList(tempClass.getDeclaredFields()));
if (!map.containsKey(className)) {
map.put(className, fields);
}
tempClass = tempClass.getSuperclass();
}
Set<String> classNames = map.keySet();
for (String className : classNames) {
List<Field> fields = map.get(className);
for (Field field : fields) {
log.debug("遞歸獲取所有類的成員變量%s.%s", className, field.getName());
}
}
}
c.獲取成員變量的修飾符
/**
* 變量的修飾符是通過int類型的數字表示的
* 常見的數字與修飾符關係如下
* int publicCode = Modifier.PUBLIC;//1
int privateCode = Modifier.PRIVATE;//2
int protectedCode = Modifier.PROTECTED;//4
int staticCode = Modifier.STATIC;//8
*/
@Test
public void getFieldModifiers(){
Class clazz=UserInfo.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field :fields)
{
int modify = field.getModifiers();
log.debug("獲取成員變量的修飾符field=%s---modifer=%s",field.getName(),modify);
}
}
d.獲取成員變量的數據類型
/**
* 獲取變量的類型之後可以通過判斷變量類型給變量賦值
*/
@Test
public void getFieldType(){
Class clazz=UserInfo.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field :fields)
{
Type type = field.getGenericType();
//其實這樣獲取的就是這個類的class對象
Class fieldClazz= (Class) type;
log.debug("獲取成員變量的修飾符field=%s---type=%s",field.getName(),fieldClazz.getName());
}
}
2.常用對象-Method
3.常用對象-Constructor