首页 > 其他分享 >Jvm(day2—class初始化过程)

Jvm(day2—class初始化过程)

时间:2022-09-25 23:57:04浏览次数:57  
标签:name day2 public Jvm 加载 data class String

Class初始化过程

 

  •  加载

  jvm将.class文件以二进制的形式读取到内存(.class文件本身是2进制的,但其文件内容是16进制的字节码),存放在方法区(类的元信息),并在堆区创建Class对象(类的实例,用于封装方法区的数据结构)。

 

    • 双亲委派模型

  约定类加载器的加载机制:根加载器 > 扩展加载器 > 系统加载器 > 自定义加载器,当类加载器收到类加载请求时,总是先委派父类加载器去完成,只有当父类加载器无法加载时,才会尝试自己加载。

  目的:保证了类的全局唯一性

 

    • 如何打破jdk默认的双亲委派机制?
继承ClassLoader,并重写loadClass
public class MyClassLoader extends ClassLoader {

    private String path;

    public MyClassLoader(String classLoaderName) {
        super();
    }

    public MyClassLoader(ClassLoader parent, String classLoaderName) {
        super(parent);
    }

    /**
     * 寻找加载类
     * @param name
     * @return
     */
    @Override
    protected Class<?> findClass(String name) {
        byte[] data = this.loadClassData(name);
        return super.defineClass(name, data, 0, data.length);
    }

    /**
     * 根据地址加载class文件。
     *
     * @param name
     * @return byte数组
     */
    private byte[] loadClassData(String name) {
        InputStream is = null;
        byte[] data = null;
        ByteArrayOutputStream baos = null;
        try {
            name = name.replace(".", "\\");
            JarFile jar = new JarFile(this.path);
            is = jar.getInputStream(jar.getEntry(name.replace("\\", "/") + ".class"));
            baos = new ByteArrayOutputStream();
            int ch;
            while (-1 != (ch = is.read())) {
                baos.write(ch);
            }
            data = baos.toByteArray();
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            try {
                is.close();
                baos.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return data;
    }

    public void setPath(String path) {
        this.path = path;
    }
}
public class MyTest {
    public static void main(String[] args) throws Exception{
        ClassLoader classloader = Thread.currentThread().getContextClassLoader();
        Enumeration<URL> urls = classloader.getResources("com/DataManager.class");
        while (urls.hasMoreElements()) {
            String[] jarPath = urls.nextElement().getPath().split("!");
            // 获取文件的路径以及文件名
            String filePath = jarPath[0].replace("file:/","");
            String classPath = jarPath[1].substring(1).replace(".class", "").replace("/", ".");
            MyClassLoader loader = new MyClassLoader(null, "myClassLoader");

            loader.setPath(filePath);
            // 加载类
            Class<?> clazz = loader.loadClass(classPath);
            // 反射创建实体
            Object obj = clazz.getDeclaredConstructor().newInstance();
            Method method = clazz.getMethod("go", String.class);
            System.out.println(method.invoke(obj, "text"));
        }
    }
}
  • 连接
    • 验证:保证.class文件符合jvm要求
    • 准备:为静态变量设置默认值(静态变量存储在方法区,实例变量随对象一起被分配到堆区;若静态变量被final修饰,则直接显示赋值)
    • 解析:将符号引用(仅仅是个临时的常量符号来表示引用)转为直接引用(即指针,如指向Class对象、类变量、类方法的指针)

 

标签:name,day2,public,Jvm,加载,data,class,String
From: https://www.cnblogs.com/dork-h/p/16729440.html

相关文章

  • Python中class内置方法__init__与__new__作用与区别探究
    背景最近尝试了解Django中ORM实现的原理,发现其用到了metaclass(元类)这一技术,进一步又涉及到Pythonclass中有两个特殊内置方法__init__与__new__,决定先尝试探究一番两者......
  • Jvm(day1—基础篇)
     Jvm基础知识点 jvm、jre、jdk的关系?jvm:java虚拟机,能够识别.class文件,解析指令并调用操作系统上的函数完成操作;jre:java运行时环境(javaruntimeenvi......
  • Vue中Class 与 Style 绑定如何加样式
    你可以在对象中传入更多字段来动态切换多个class。此外,v-bind:class 指令也可以与普通的classattribute共存。当有如下模板:<divclass="static"v-bind:class="{act......
  • Day2 :CMD学习笔记
    CMD学习笔记常见dos命令#盘符切换(X:)#查看当前目录下的全部文件夹(dir)#返回上一级(cd..)#跨盘符切换文件夹(cd/d文件夹位置)#清理屏幕(cls)#推出exit#查询......
  • Class<String> 还是 Class< ? extends String>
    Class还是Class<?extendsString>引出问题先上代码点击查看代码Class<String>class01=String.class;Class<?extendsString>class02="h......
  • 存储类StorageClass
    存储类StorageClass是kubernetes资源类型的一种,它是由管理员为管理pv之便而按需创建的类别(逻辑组),例如可按存储系统的性能高低分类,或者根据其综合服务质量级别进行分类......
  • 性能测试之jvm
    浅谈一下在性能测试中,遇到java应用出现OOM时(内存泄漏,FGC),作为非专业java开发的测试人员如何去分析,以及调试jvm参数。在开始进行测试前,先对jvm内存分配有一个大概的了解.......
  • jvm简单介绍
    jvm是一种用于计算设备的规范,它是一种虚构出来的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现 JVM和操作系统的关系我们的操作系统是没法识别.cl......
  • create instance error, class xxx.xxx$xx类错误
    反序列化的fastjson方法Listalist=JSONObject.parseArray(Stringtext,Classclazz)例如下面这个需要反序列化的多层嵌套复杂接收对象内部类必须定义成静态的,static,不......
  • day2-doc指令的练习
    常用的dos指令 #盘符切换 #查看当前目录下的文件dir #切换目录cdchangedirectory  cd/d跨盘切换  cd..切换上级目录 #cls清理屏幕clearscreen ......