zoukankan      html  css  js  c++  java
  • 浅析类加载

    前言:总结一下类加载的过程,于静态代码块、静态变量、事例变量等一些构建方式。因为这部分挺绕的,容易出错。

    1、java中可以将对象分为两大体系:字节码对象和实例对象

    1.1、字节码对象:

    每个类在加载(将类读到内存)都会创建一个字节码对象,且这个对象在一个JVM内存中是唯一.此对象中存储的是类的结构信息.所以可以说字节码对象是获取类结构信息的入口.

    每个类对应的类字节码文件在jvm中都是唯一的【验证】

    1     /**
    2      * 测试类的字节码文件是否是唯一的
    3      */
    4     private static void testClassLoader_01(){
    5         Class<?> class_1 = Object.class;
    6         Class<?> class_2 = Object.class;
    7         System.out.println(class_1 == class_2);
    8         // 输出结果:true
    9     }

    字节码对象的获取方式?(常用方式有三种)

    • 类名.class可以使用Class<?> Class<类名>来接收
    • Class.forName(“包名.类名”)编译阶段无法确定字符串对应的类名是否准确,只能用Class<?>泛型通配符来接收
    • 类的实例对象.getClass()
     1     /**
     2      * 三种类加载方式
     3      */
     4     private static void testClassLoader_02() throws ClassNotFoundException {
     5         Class<?> class_1 = Object.class;
     6         Class<?> class_2 = Class.forName("java.lang.Object");
     7         Class<?> class_3 = new Object().getClass();
     8         System.out.println((class_1 == class_2)&&(class_2 == class_3));
     9         // 注意:三种类加载方式,加载的是同一个类字节码文件
    10     }

    类加载时:

      静态代码块:可以执行,但不一定会执行。

      静类变量:可以初始化,但不一定会初始化。

    1 class C_Object{
    2     static{
    3         System.out.println("进入了静态代码块");
    4     }
    5 }
    1     private static void testClassLoader_03() throws ClassNotFoundException {
    2         // 这个不会输出 进入了静态代码块
    3         Class<?> class_1 = Object.class;
    4         // 这个会输出  进入了静态代码块
    5         Class<?> class_2 = Class.forName("com.turtle.oop.C_Object");
    6     }

     对Class.forName()进行剖析:

    1      // arg1:这个是我们要加载的字节码类   
    2         // arg2:这个是确定我们在类加载的时候是否执行静态代码块,默认是true,执行,如果为false就不会执行静态代码块
    3         // arg3:使用类加载器来完成类的加载
    4         Class<?> c3 = Class.forName("com.turtle.oop.ClassObject",true,Thread.currentThread().getContextClassLoader());

    总结案例:

     1 package com.turtle.oop;
     2 
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 public class Test_ClassLoader_02 {
     7     public static void main(String [] args) throws ClassNotFoundException {
     8         Class<?> class_01 = Class.forName("com.turtle.oop.C_Object_2",true,Thread.currentThread().getContextClassLoader());
     9         // 出错
    10     }
    11 }
    12 class C_Object_2{
    13 /*    为类中的静态变量赋值是按顺序下来的
    14     1-加载ClassObject_03类到内存中
    15     2-为ClassObject_03类型的变量instance赋值,会调用构造方法
    16     3-构造方法中使用了静态变量map,但是此时的静态变量map还没有赋值*/
    17     static C_Object_2 instance=new C_Object_2();
    18     // 如果和上面的交换位置也就不会出错了、如果改为非静态的就不会出错了
    19     static Map<String,String> map = new HashMap<>();
    20     public C_Object_2(){
    21         map.put("Key_01","Value_01");
    22     }
    23 }

     报错:空指针错误

    D:ProgramsJDK8injava.exe "-javaagent:D:ProgramsJetBrainsIntelliJ IDEA 2018.3.5libidea_rt.jar=55074:D:ProgramsJetBrainsIntelliJ IDEA 2018.3.5in" -Dfile.encoding=UTF-8 -classpath D:ProgramsJDK8jrelibcharsets.jar;D:ProgramsJDK8jrelibdeploy.jar;D:ProgramsJDK8jrelibextaccess-bridge-64.jar;D:ProgramsJDK8jrelibextcldrdata.jar;D:ProgramsJDK8jrelibextdnsns.jar;D:ProgramsJDK8jrelibextjaccess.jar;D:ProgramsJDK8jrelibextjfxrt.jar;D:ProgramsJDK8jrelibextlocaledata.jar;D:ProgramsJDK8jrelibext
    ashorn.jar;D:ProgramsJDK8jrelibextsunec.jar;D:ProgramsJDK8jrelibextsunjce_provider.jar;D:ProgramsJDK8jrelibextsunmscapi.jar;D:ProgramsJDK8jrelibextsunpkcs11.jar;D:ProgramsJDK8jrelibextzipfs.jar;D:ProgramsJDK8jrelibjavaws.jar;D:ProgramsJDK8jrelibjce.jar;D:ProgramsJDK8jrelibjfr.jar;D:ProgramsJDK8jrelibjfxswt.jar;D:ProgramsJDK8jrelibjsse.jar;D:ProgramsJDK8jrelibmanagement-agent.jar;D:ProgramsJDK8jrelibplugin.jar;D:ProgramsJDK8jrelib
    esources.jar;D:ProgramsJDK8jrelib
    t.jar;D:ProjectHomeWorks_FrameWork1-JavaEE-Heightenjavaee	argetclasses com.turtle.oop.Test_ClassLoader_02
    Exception in thread "main" java.lang.ExceptionInInitializerError
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:348)
        at com.turtle.oop.Test_ClassLoader_02.main(Test_ClassLoader_02.java:8)
    Caused by: java.lang.NullPointerException
        at com.turtle.oop.C_Object_2.<init>(Test_ClassLoader_02.java:15)
        at com.turtle.oop.C_Object_2.<clinit>(Test_ClassLoader_02.java:12)
        ... 3 more
    
    Process finished with exit code 1
  • 相关阅读:
    获取有关控件的坐标
    Android PopupWindow的使用和分析
    Android RecyclerView 使用完全解析 体验艺术般的控件
    TextView中显示价格并且中间直接有一个横线
    Android Studio
    移动开发】Android中三种超实用的滑屏方式汇总(ViewPager、ViewFlipper、ViewFlow)
    Android中visibility属性VISIBLE、INVISIBLE、GONE的区别
    理解Java的IO流 2015年8月6日 21:30:38
    算法导论学习随笔——第七章 快速排序
    oj 1031 random permutation
  • 原文地址:https://www.cnblogs.com/zhh19981104/p/10740348.html
Copyright © 2011-2022 走看看