java 反射机制详解
来源:互联网 发布:linux中进程怎么调度 编辑:程序博客网 时间:2024/05/27 09:47
java 反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。
java 反射类加载的生命周期:
在程序执行中JVM通过装载,链接,初始化这3个步骤完成。
类的装载是通过类加载器完成的,加载器将.class文件的二进制文件装入JVM的方法区,并且在堆区创建描述这个类的java.lang.Class对象。
但是同一个类只会被类装载器装载以前
链接:就是把二进制数据组装为可以运行的状态。
链接分为:校验,准备,解析这3个阶段
校验:一般用来确认此二进制文件是否适合当前的JVM(版本),
准备:就是为静态成员分配内存空间,。并设置默认值
解析:指的是转换常量池中的代码作为直接引用的过程,直到所有的符号引用都可以被运行程序使用(建立完整的对应关系)
完成之后,类型也就完成了初始化,初始化之后类的对象就可以正常使用了,直到一个对象不再使用之后,将被垃圾回收,释放空间。
当没有任何引用指向Class对象时就会被卸载,结束类的生命周期
package com.bjhy.platform.criminal.search.report.test;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.LinkedHashMap;import java.util.List;import com.bjhy.platform.criminal.search.core.annotation.ColumnConfig;/** * java反射 * @author wbw * */public class MyReflect {/** *获取一个领域对象的完整包名和类名 * @param className 领域对象 * @return 领域对象完整包名和类名 */public static String getClassName(Class<?> clzz){return clzz.getName();}/** * jvm运行时期获取指定实体类的属性,属性类型 * @param clzz 类名 * @return 类属性、属性类型 */public static String getClassField(Class<?> clzz){Field[] fields = clzz.getFields();StringBuffer sb = new StringBuffer();for(Field field :fields){//属性名称sb.append(field.getName());// 属性类型sb.append(field.getType().getName());sb.append(",");}String str = sb.substring(0, sb.length() - 1);return str;}/** * 获取指定实体类的父类 * @param clzz 指定的实体类 * @return 实体类的父类 */public static String getSuperClassName(Class<?> clzz){return clzz.getSuperclass().getName();}/** * 反射调用静态方法 * @param className 实体类的完整包名和类名 */public static void getStaticMethod(String className){Class cls = null;try {cls = Class.forName(className);Method sm = cls.getDeclaredMethod("hello", int.class,String.class);sm.invoke(cls, 20,"xw");} catch (Exception e) {e.printStackTrace();}}/** * 反射为实体类private的属性赋值 * @param className */public static void setFieldValue(String className){Class cls = null;try {cls = Class.forName(className);Object user = cls.newInstance();Field field = cls.getDeclaredField("name");field.setAccessible(true);//设置字段为允许访问field.set(user, "xw");System.out.println(field.get(user));} catch (Exception e) {e.printStackTrace();}}/** * * 获取实体类的类加载器 * java 有三种类加载器 * 1.Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。 2.Extension ClassLoader 用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类 3.AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。 * @param clzz * @return */public static String getClassLoader(Class<?> clzz){return clzz.getClassLoader().getClass().getName();}/** * 工厂内部类,一般的工厂模式都是通过判断传入的对象类型而不做不同的操作,但是在增加多个子类的时候,就需要频繁的修改工厂类, * 但是如果使用反射机制将会在不改变工厂类的情况下操作子类 * @author wbw * */class Factory{/** * 一般情况下的工厂模式 * @param className * @return */@SuppressWarnings("unused")public User demo1(String className){User user = null;if(className.equals("normal")){return user = new User();}else if(className.equals("ammin")){return user = new ManageUser();}return null;}/** * 反射工厂模式 * @param className * @return */public User demo(String className) throws Exception{return (User) Class.forName(className).newInstance();}}/** * 根据实体类名获取属性名称和使用自定义注解设置的属性中文名称 * @param clzz 实体类名 * @return List<Map<String,Object>> */public static List<LinkedHashMap<String,Object>> initAnnoFieldDic(Class<?> clzz){ //使用List<LinkedHashMap<String,Object>>用于存储字段和中文值的集合//LinkedHashMap<String,Object> key为类.属性,value为属性的中文名称List<LinkedHashMap<String,Object>> fieldList = new ArrayList<>();LinkedHashMap<String,Object> valueMap = new LinkedHashMap<>(); //获取对象中所有的Fields Field[] fields = clzz.getDeclaredFields(); //循环实体类字段集合,获取标注自定义注解@ColumnConfig的属性 for (Field field : fields) { if(field.isAnnotationPresent(ColumnConfig.class)){ //获取字段名 String fieldNames = clzz.getSimpleName()+"."+field.getName(); //获取字段注解 ColumnConfig columnConfig = field.getAnnotation(ColumnConfig.class); //判断是否已经获取过该code的字典数据 避免重复获取 if(valueMap.get(columnConfig.description())==null){ valueMap.put(fieldNames, columnConfig.description()); } } } fieldList.add(valueMap);return fieldList;}}
Class文件只是一种静态格式的二进制流,它只有被虚拟机加载进内存解析之后才会生成真正的运行时的结构,因此,搞清楚类加载机制不但有助于我们加深理解Class文件中各个字段的含义,同时也有利于我们更深入的了解JAVA。
最后附上java反射类加载图,便于更好的理解
0 0
- java反射机制详解!
- java 反射机制详解
- JAVA反射机制详解
- java反射机制详解
- Java反射机制详解
- Java反射机制详解
- java反射机制详解
- Java反射机制详解
- Java反射机制详解
- JAVA反射机制详解
- java反射机制详解
- Java反射机制详解
- Java反射机制详解
- java反射机制详解
- Java反射机制详解
- java反射机制详解
- Java反射机制详解
- Java反射机制详解
- 手把手教你做爬虫---基于NodeJs
- Hibernate三种检索策略的优缺点对比
- LeetCode 235. Lowest Common Ancestor of a Binary Search Tree
- API接口设计 - 身份认证篇
- 集合竞价 CCF java实现 (大部分代码是借鉴的别人的,)
- java 反射机制详解
- 常用服务的端口
- JAVA操作mongoDB
- Hadoop namenode 不能启动解决方案
- python 爬虫好文 urllib cookie beautifulsoap
- IO流笔记第五发缓冲流读写及简单file类操作
- Objective-C页面消失或出现时,判断是pop还是push操作
- 内存MCE错误导致暴力扩充messages日志 以及chattr记录
- 字符串反序