codecamp

第16篇-JAVA 类加载与反射

  • 每篇一句 :敢于弯曲,是为了更坚定的站立
  • 初学心得: 追求远中的欢声笑语,追求远中的结伴同行
  • (笔者:JEEP/711)[JAVA笔记 | 时间:2017-05-12| JAVA 类加载与反射 ]

1.类加载

  • 类加载器负责将 .class 文件(可能在磁盘上, 也可能在网络上) 加载到内存中, 并为之生成对应的 java.lang.Class 对象
    - 当程序主动使用某个类时,如果该类还未被加载到内存中,系统会通过加载、连接、初始化三个步骤来对该类进行初始化,如果没有意外,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或类初始化。
    - 类加载指的是将类的class文件读入内存,并为之创建一个java.lang.Class对象,也就是说当程序使用任何类时,系统都会为之建立一个java.lang.Class对象

2.类数据的来源

通过使用不同的类加载器,可以从不同来源加载类的二进制数据,通常有如下几种来源:
- 从本地文件系统来加载class文件,这是前面绝大部分示例程序的类加载方式。
- 从JAR包中加载class文件,这种方式也是很常见的,前面介绍JDBC编程时用到的数据库驱动类就是放在JAR文件中,JVM可以从JAR文件中直接加载该class文件
- 通过网络在加载class文件
- 把一个Java源文件动态编译、并执行加载

3.类的连接

当类被加载之后,系统为之生成一个对应的Class对象,接着将会进入连接阶段,连接阶段将会负责把类的二进制数据合并到JRE中

类连接又可分为如下三个阶段:
- 验证:验证阶段用于检验被加载的类是否有正确的内部结构,并和其他类协调一致
- 准备:类准备阶段则负责为类的静态属性分配内存,并设置默认初始值
- 解析:将类的二进制数据中的符号引用替换成直接引用

4.类加载器

类加载器负责将.class文件(可能在磁盘上,也可能在网络上)加载到内存中,并为之生成对应的java.lang.Class对象

当JVM启动时,会形成由三个类加载器组成的初始类加载器层次结构:
- Bootstrap ClassLoader:根类加载器。
- Extension ClassLoader:扩展类加载器。
- System ClassLoader:系统类加载器

5.什么是反射

反射就是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象

6.Class类

Class类用于表示.class文件
如何得到某个class文件对应的class对象

类名.class,
对象.getClass()
Class.forName(“类名”)

数组类型的Class实例对象

Class.isArray()

7.Constructor类

Constructor类的实例对象代表类的一个构造方法
得到某个类所有的构造方法,例:

Constructor [] constructors= Class.forName("java.lang.String").getConstructors();

得到某一个构造方法,例:


Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);

利用构造方法创建实例对象:

String str = (String)constructor.newInstance(“abc”);

Class类的newInstance()方法也可创建类的实例,其内部工作原理是先得无参的构造方法,再用构造方法创建实例对象

String obj =(String)Class.forName("java.lang.String").newInstance();

8.内省(Introspector)

访问JavaBean属性的两种方式
- 直接调用bean的setXXX或getXXX方法
- 通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式
- 通过PropertyDescriptor类操作Bean的属性
- 通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法

内省—beanutils工具包
Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写

Beanutils工具包的常用类:
- BeanUtils
- PropertyUtils
- ConvertUtils.regsiter(Converter convert, Class clazz)
- 自定义转换器

9.反射案例


<br> package com.mvc.bean;
<br> import com.mvc.service.imp.UserServiceImp;
<br> import java.util.ResourceBundle;
<br> /**
<br>  * Created by JEEP-711 
<br>  */
<br> public class BeanFactory {
<br>     private static ResourceBundle bundle;
<br>     static {
<br>         bundle = ResourceBundle.getBundle("instance"); //文件内容
<br>     }
<br>     public static <T& T getInstance(String key, Class<T& clazz){
<br>         try {
<br>             String className = bundle.getString(key);//类的全路径
<br>             return (T)Class.forName(className).newInstance();//反射方式
<br>         } catch (Exception e) {
<br>             throw new RuntimeException(e);
<br>         }
<br>     }
<br> }
<br> ```
<br> ```
<br> package com.mvc.controller;
<br> import com.alibaba.fastjson.JSON;
<br> import com.mvc.bean.BeanFactory;
<br> import com.mvc.bean.Type;
<br> import com.mvc.service.ITypeService;
<br> import com.mvc.service.imp.TypeServiceImpl;
<br> import org.apache.commons.beanutils.BeanUtils;
<br> import javax.servlet.ServletException;
<br> import javax.servlet.http.HttpServlet;
<br> import javax.servlet.http.HttpServletRequest;
<br> import javax.servlet.http.HttpServletResponse;
<br> import java.io.IOException;
<br> import java.io.Writer;
<br> import java.util.List;
<br> /**
<br>  * Created by JEEP-711 
<br>  */
<br> public class TypeServlet extends HttpServlet{
<br>                                                //反射
<br> ITypeService iTypeService = BeanFactory.getInstance("typeService",ITypeService.class);
<br>     @Override
<br>     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
<br>         resp.setContentType("text/html;charset=UTF-8");//设置UTF-8编码格式
<br>         req.setCharacterEncoding("UTF-8");//设置UTF-8编码格式
<br>         String method = req.getParameter("m");
<br>         if("add".equals(method)){
<br>             add(req,resp);//调用add方法
<br>         }else if("update".equals(method)){
<br>             update(req,resp);//调用修改方法
<br>         }else if("ajax_all".equals(method)){
<br>             ajaxAll(req,resp);
<br>         }else if("delete".equals(method)){
<br>             delete(req,resp);
<br>         }else {
<br>             index(req,resp);//调用错误方法
<br>         }
<br>     }
<br> }
<br> ```

初学(JAVA 类加载与反射 高级阶段) 难点: ★★★★★

希望每一篇文章都能够对读者们提供帮助与提升,这乃是每一位笔者的初衷

感谢您的阅读 欢迎您的留言与建议

第15篇-JAVA JDBC编程
第17篇-JAVA Annotation 注解
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }