Java 反射的再次学习
1 概述
这段时间,又用到了java的反射技术,结果发现如此的陌生,结果在极客学院上搜到一个视频,感觉不错,就写个博客再记录一下吧。
2 Java反射
都说反射实际上java本身留下的后门,因为只要拿到了类的名称,就相当于在运行时拿到了类的所有信息,包含私有函数与变量、其父类中的方法。
2.1 测试用例
<pre name="code" class="java">package com.reflect.test.annimals;
public class Annimals {
private String annimalType;
private String annimalMaster;
private String annimalName;
private int annimalYear;
public String getAnnimalType() {
return annimalType;
}
public void setAnnimalType(String annimalType) {
this.annimalType = annimalType;
}
public String getAnnimalMaster() {
return annimalMaster;
}
public void setAnnimalMaster(String annimalMaster) {
this.annimalMaster = annimalMaster;
}
public String getAnnimalName() {
return annimalName;
}
public void setAnnimalName(String annimalName) {
this.annimalName = annimalName;
}
public int getAnnimalYear() {
return annimalYear;
}
public void setAnnimalYear(int annimalYear) {
this.annimalYear = annimalYear;
}
}
2.2 Class对象的机制和实现
2.2.1 常用方法
方法名 | 方法含义 |
getName() | 获得类中的完整名称 |
getDeclaredFields() | 获得类中的所有属性 |
getDeclaredMethods() | 获得类中的所有方法 |
getConstructors() | 获得类中的构造方法 |
newInstance() | 实例化对象 |
2.2.2 实现案例
<pre name="code" class="java">package com.reflect.test.program;
import com.reflect.test.annimals.Annimals;
public class ClassTest {
//获取类的名字的几种方式
public static void main(String[] args) {
// TODO Auto-generated method stub
Class cls_1 = null;
Class cls_2 = null;
Class cls_3 = null;
try {
cls_1 = Class.forName("com.reflect.test.annimals.Annimals");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("第一种方式为:" + cls_1);
cls_2 = Annimals.class;
System.out.println("第二种方式为:" + cls_2);
Annimals annimal_1 = new Annimals();
Object obj = annimal_1;
System.out.println("第三种方式为:" + obj.getClass());
try {
Annimals annimal_2 = (Annimals) cls_2.newInstance();//实例化对象
System.out.println("第四种方式为:" + annimal_2);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
第一种方式为:class com.reflect.test.annimals.Annimals
第二种方式为:class com.reflect.test.annimals.Annimals
第三种方式为:class com.reflect.test.annimals.Annimals
第四种方式为:com.reflect.test.annimals.Annimals@1db9742
}
2.3 Field对象的机制和实现
2.3.1 常用方法
方法名 | 方法含义 |
getName() | 获得属性的完整名称 |
getType() | 获得属性类型 |
get(Object obj) | 获得obj对象中这个属性的值 |
set(Object obj, Object value ) | 对obj对象中属性赋值value |
setAccessible(true) | 启用(true)/禁用(默认或者是false)访问控制权限,比如需要使用上/上一行的set和get函数 |
2.3.2 实现案例
package com.reflect.test.program;
import java.lang.reflect.Field;
import com.reflect.test.annimals.Annimals;
public class FieldTest {
public void FieldOperation(Class cl) {
Field[] field_1 = cl.getDeclaredFields();
System.out.println("依次打印getDeclaredFields获得的参数:" );
for(Field fi : field_1) {
System.out.println("第一种方法:" + fi.getName());
System.out.println("第一种方法:" + fi.getType());
}
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
Field[] field_2 = cl.getFields();
System.out.println("依次打印getFields获得的参数:" );
for(Field fi : field_2) {
System.out.println("第二种方法:" + fi.getName());
System.out.println("第二种方法:" + fi.getType());
}
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
}
public void FieldOperation(Object obj) {
Class cl = obj.getClass();
Field[] field_4 = cl.getDeclaredFields();
System.out.println("依次打印getDeclaredFields获得的参数值:" );
for(Field fi : field_4) {
fi.setAccessible(true);
System.out.println("第三种方法:" + fi.getName());
try {
System.out.println("第三种方法:" + fi.get(obj));
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Annimals annimals = new Annimals();
annimals.setAnnimalType("Dog");
annimals.setAnnimalMaster("host");
annimals.setAnnimalName("heibei");
annimals.setAnnimalYear(15);
FieldTest fieldtest = new FieldTest();
fieldtest.FieldOperation(Annimals.class);
fieldtest.FieldOperation(annimals);
}
}
依次打印getDeclaredFields获得的参数:
第一种方法:annimalType
第一种方法:class java.lang.String
第一种方法:annimalMaster
第一种方法:class java.lang.String
第一种方法:annimalName
第一种方法:class java.lang.String
第一种方法:annimalYear
第一种方法:int
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
依次打印getFields获得的参数:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
依次打印getDeclaredFields获得的参数值:
第三种方法:annimalType
第三种方法:Dog
第三种方法:annimalMaster
第三种方法:host
第三种方法:annimalName
第三种方法:heibei
第三种方法:annimalYear
第三种方法:15
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2.4 Method对象的机制与实现
2.4.1 常用方法
方法名 | 方法含义 |
getName() | 获得方法名称 |
getReturnType() | 获得方法的返回值类型 |
invoke(Object obj, Object args) | 利用obj对象调用该方法 |
getParameterTypes() | 获得方法的所有参数类型,按照顺序返回Class数组 |
getDeclaredAnnotation() | 获取方法的全部注解 |
2.4.2 实现案例
package com.reflect.test.program;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import com.reflect.test.annimals.Annimals;
public class MethodTest {
public void MethodProperty(Object obj) {
Class cl = obj.getClass();
Method[] method = cl.getDeclaredMethods();
for (Method mm : method) {
System.out.println("方法名称:" + mm.getName());
System.out.println("方法修饰符:" + mm.getModifiers());
System.out.println("方法返回值类型:" + mm.getReturnType());
}
}
public void MethodOperation(Object obj) {
Class cl = obj.getClass();
try {
Method method_1 = cl.getMethod("getAnnimalName", null);
method_1.invoke(obj, new Object[0]);
Method method_2 = cl.getMethod("setAnnimalName", String.class);
method_2.invoke(obj, "Cat");
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Annimals annimals = new Annimals();
annimals.setAnnimalType("Dog");
annimals.setAnnimalMaster("host");
annimals.setAnnimalName("heibei");
annimals.setAnnimalYear(15);
MethodTest methodtest = new MethodTest();
methodtest.MethodProperty(annimals);
methodtest.MethodOperation(annimals);
System.out.println("修改后的结果为:" + annimals.getAnnimalName());
}
}
方法名称:getAnnimalName
方法修饰符:1
方法返回值类型:class java.lang.String
方法名称:setAnnimalName
方法修饰符:1
方法返回值类型:void
方法名称:setAnnimalType
方法修饰符:1
方法返回值类型:void
方法名称:setAnnimalMaster
方法修饰符:1
方法返回值类型:void
方法名称:setAnnimalYear
方法修饰符:1
方法返回值类型:void
方法名称:getAnnimalType
方法修饰符:1
方法返回值类型:class java.lang.String
方法名称:getAnnimalMaster
方法修饰符:1
方法返回值类型:class java.lang.String
方法名称:getAnnimalYear
方法修饰符:1
方法返回值类型:int
修改后的结果为:Cat