javaSE_反射
反射就是可以通过程序动态的去修改jvm虚拟机已经加载好的方法区里面的属性、成员变量。
通过反射获取类:
Class clz = Class.forName(“com.gary.model.Student”);
- 创建对象
通过类创建对象:
Student obj = (Student) clz.newInstance();// 通过类创建对象
通过构造函数创建对象:
System.out.println(“—————获取不带参构造函数-—————“);
Constructor constructor1 = clz.getDeclaredConstructor();
Student object1 = (Student) constructor1.newInstance();// 通过构造函数创建对象
System.out.println(object1.getName());
System.out.println(“—————获取带参构造函数-—————“);
Constructor constructor2 = clz.getDeclaredConstructor(String.class, Integer.class);
Student object2 = (Student) constructor2.newInstance(“gary”, 20);
System.out.println(object2.getName());
System.out.println(“—————封装泛型,通过类创建对象-—————“);
Student object3 = ReflectUtils.getObject(clz, “mary”, 22);
System.out.println(object3.getName());
输出:
-————-获取不带参构造函数-—————
null
-————-获取带参构造函数-—————
gary
-————-封装泛型,通过类创建对象-—————
mary
public class ReflectUtils {
// 通过包名创建class
public static Class getClass(String className){
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
// 通过class创建对象
public static
try {
Class[] types = new Class[params.length];
for (int i = 0; i < params.length; ++i){
types[i] = params[i].getClass();
}
Constructor constructor = clz.getDeclaredConstructor(types);
return (T) constructor.newInstance(params);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
- 解析构造函数
获取所有构造函数:
//Constructor[] constructors = clz.getConstructors();// 只能访问public的构造函数
Constructor[] constructors = clz.getDeclaredConstructors();// 访问所有修饰符的构造函数
for (Constructor constructor : constructors){
System.out.println(“构造函数名称:” + constructor.getName());
System.out.println(“构造函数修饰符:” + constructor.getModifiers());
Class[] types = constructor.getParameterTypes();
for (Class class1 : types){
System.out.print(class1.getName() + “\t”);
}
}
输出:
构造函数名称:com.gary.model.Student
构造函数修饰符:1
构造函数名称:com.gary.model.Student
构造函数修饰符:1
java.lang.Stringjava.lang.Integer
可见有两个构造函数,一个无参一个有参。
获取单个构造函数:
Constructor constructor1 = clz.getDeclaredConstructor();
Constructor constructor2 = clz.getDeclaredConstructor(String.class, Integer.class);
- 解析属性
public static void Reflect_Field(){
System.out.println(“—————field—————“);
try {
Class clz = Class.forName(“com.gary.model.Student”);
Student stu = (Student) clz.newInstance();
stu.setAge(31);
// 获取所有属性
Field[] fields = clz.getDeclaredFields();
for (Field field : fields){
System.out.println(“修饰符:” + field.getModifiers());
System.out.println(“类型:” + field.getType());
System.out.println(“名称:” + field.getName());
System.out.println(“————————————“);
}
// 通过属性名获取属性
Field field = clz.getDeclaredField(“age”);
System.out.println(“通过名称获取的属性名:” + field.getName());
field.setAccessible(true);// 获取私有成员必须添加此设置
System.out.println(“获取对象的值:” + field.get(stu));
} catch (Exception e) {
e.printStackTrace();
}
}
其中student类属性如下:
public class Student {
private Integer age;
protected String name;
}
输出:
-————-field—————
修饰符:2
类型:class java.lang.Integer
名称:age
-———————————-
修饰符:4
类型:class java.lang.String
名称:name
-———————————-
通过名称获取的属性名:age
获取对象的值:31
// 获取对象的某一成员变量值(一般都是通过方法获取,很少直接获取变量的)
public static Object getPropertyValue(Object obj, String fieldName){
Class clz = obj.getClass();
try {
Field field = clz.getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(obj);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
- 解析方法
public static void Reflect_Method(){
System.out.println(“—————method—————“);
try {
Class clz = Class.forName(“com.gary.model.Student”);
// 获取所有方法
Method[] methods = clz.getDeclaredMethods();
for (Method method : methods){
System.out.println(“修饰符:” + method.getModifiers());
System.out.println(“名称:” + method.getName());
System.out.println(“返回类型:” + method.getReturnType());
Class[] parameters = method.getParameterTypes();
for (Class parameter : parameters){
System.out.println(“参数类型:” + parameter.getName());
}
System.out.println(“————————————“);
}
// 获取某一具体方法
Method method = clz.getDeclaredMethod(“setAge”, Integer.class);
System.out.println(“获取具体方法名:” + method.getName());
Student student = (Student) clz.newInstance();
// 执行方法
method.invoke(student, 22);
System.out.println(student.getAge());
} catch (Exception e) {
e.printStackTrace();
}
}
封装一下获取函数:
public class ReflectUtils {
// 通过方法名获取方法
public static Method getMethod(Class clz, String methodName, Class…parameterTypes){
try {
return clz.getDeclaredMethod(methodName, parameterTypes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 通过成员变量名获取其et方法
public static Method getMethod_FieldGet(Class clz, String fieldName){
try {
Field field = clz.getDeclaredField(fieldName);
String methodName = fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
return getMethod(clz, “get”+methodName);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
// 通过成员变量名获取其set方法
public static Method getMethod_FieldSet(Class clz, String fieldName){
try {
Field field = clz.getDeclaredField(fieldName);
String methodName = fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
return getMethod(clz, “set”+methodName, field.getType());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
- 解析注解
自定义一个注解类,将此注解添加到类上、属性上、方法上等等,就可以通过类拿到注解的信息。
创建一个自定义类:
// @Documented说明该注解将被包含在javadoc中
@Documented
// @Retention指定编译器对自定义注解的策略
@Retention(value=RetentionPolicy.RUNTIME)
// @Target指定此注解的使用范围
@Target({
ElementType.TYPE,// 接口、类、枚举、注解
ElementType.FIELD,// 字段、枚举的常量
ElementType.METHOD,// 方法
ElementType.PARAMETER,//方法参数
ElementType.CONSTRUCTOR,// 构造函数
ElementType.LOCAL_VARIABLE,// 局部变量
ElementType.ANNOTATION_TYPE,// 注解
ElementType.PACKAGE // 包
})
public @interface LogMapping {
String value() default “”;// 值
String desc() default “”;// 描述
boolean mark() default true;// 标记
}
在user类上添加注解:
@LogMapping(desc=”用户类”)
public class User {
private String id;
@LogMapping(value=”name”, desc=”姓名”)
private String name;
@LogMapping(value=”age”, desc=”年龄”)
private Integer age;
@LogMapping(desc=”构造函数”)
public User() {
}
@LogMapping(value=”getId”, desc=”获取主键”)
public String getId() {
return id;
}
@LogMapping(value=”setId”, desc=”设置主键”)
public void setId(@LogMapping(desc=”id参数”) String id) {
this.id = id;
}
}
测试代码,解析注解:
// 注解
public static void Reflect_Annotation(){
System.out.println(“————— 注解-————-“);
try {
Class clz = Class.forName(“com.gary.model.User”);
// 获取类的注解
LogMapping logMapping = (LogMapping) clz.getAnnotation(LogMapping.class);
if (logMapping != null){
System.out.println(“类上注解:” + logMapping.desc());
}
// 构造函数的注解
Constructor[] constructors = clz.getDeclaredConstructors();
for (Constructor constr : constructors){
logMapping = (LogMapping) constr.getAnnotation(LogMapping.class);
if (logMapping != null){
System.out.println(“构造函数注解:” + logMapping.desc());
}
}
// 方法上的注解
Method[] methods = clz.getDeclaredMethods();
for (Method method : methods){
logMapping = (LogMapping) method.getAnnotation(LogMapping.class);
if (logMapping != null){
System.out.println(“方法上的注解:” + logMapping.desc());
}
// 参数里的注解
Annotation[][] annotations = method.getParameterAnnotations();
for (Annotation[] annotation : annotations){
for (Annotation anno : annotation){
logMapping = (LogMapping) anno;
if (logMapping != null){
System.out.println(“参数里的注解:” + logMapping.desc());
}
}
}
}
// 属性上的注解
Field[] fields = clz.getDeclaredFields();
for (Field field : fields){
logMapping = (LogMapping) field.getAnnotation(LogMapping.class);
if (logMapping != null){
System.out.println(“属性上的注解:” + logMapping.desc());
}
}
}catch (Exception e){
e.printStackTrace();
}
}
输出:
-————- 注解-————-
类上注解:用户类
构造函数注解:构造函数
方法上的注解:获取主键
方法上的注解:设置主键
参数里的注解:id参数
属性上的注解:姓名
属性上的注解:年龄
还没有评论,来说两句吧...