精华内容
下载资源
问答
  • 最近在阅读孙卫琴的java面向对象一书中,看到对java类的初始化和加载中的论述比较系统,故笔记之1)类的初始化,JAVA在初始化一个类时,以下步骤A 假如类存在直接的父类,并且这个父类还没有初始化,则先初始化直接...

    最近在阅读孙卫琴的java面向对象一书中,看到对java中类的初始化和加载中的论述比较系统,故笔记之

    1)类的初始化,JAVA在初始化一个类时,以下步骤

    A 假如类存在直接的父类,并且这个父类还没有初始化,则先初始化直接的父类

    B  假如类存在初始化的语句,那么直接执行这些初始化语句

    比如

    package init;

    class Base{

    static int a=1;

    static{

    System.out.println("init Base");

    }

    }

    class Sub extends Base{

    static int b=1;

    static{

    System.out.println("init Sub");

    }

    }

    public class InitTester{

    static{System.out.println("init InitTester");}

    /*

    public static void main(String args[]){

    System.out.println("b="+Sub.b);  //执行这行代码时,先依次初始化Base类和Sub类

    }

    */

    输出:

    init InitTester

    init Base

    init Sub

    b=1

    假如换成下面这样

    public static void main(String args[]){

    Base base;  //不会初始化Base类

    System.out.println("After defining base");

    base=new Base();  //执行这行代码时,初始化Base类

    System.out.println("After creating an object of Base");

    System.out.println("a="+base.a);

    System.out.println("b="+Sub.b);  //执行这行代码时,仅仅初始化Sub类

    }

    }

    输出

    init InitTester

    After defining base

    init  Base

    After creating an object of Base

    a=1

    init Sub

    b=1

    2) 类的初始化时机

    A 对于final类型的,如果在编译时就能计算出变量的值,则不会导致类的初始化,如下

    class Tester {

    public static final int a=2*3;

    static  {

    System.out.println("hello");   ..............

    }

    }

    public class Sample

    {

    public static void main(String args[])

    {  System.out.println("a="+Tester.a);

    }

    }

    2)  package initbase;

    class Base{  static int a=1;  static{    System.out.println("init Base");  }  static void method(){    System.out.println("method of Base");  }}class Sub extends Base{  static{    System.out.println("init Sub");  }}public class Sample{  public static void main(String args[]){    System.out.println("a="+Sub.a);  //仅仅初始化Base类    Sub.method();    }}由于静态变量a和静态方法method()在 base父类中定义,所以仅初始化Base类,没初始化SUB类打印结果为init Basea=1method of Base这样的话,如果在调用Tester.a时,不会输出hello,

    展开全文
  • 类从加载到虚拟机内存到卸载出内存,包括加载-----链接-----初始化-----使用------卸载链接具体包括:验证-----准备-----解析加载:由类加载器执行,查找字节码并从这些字节码中创建一个Class对象。链接:验证类中...

    Java程序运行由java虚拟机负责。类从加载到虚拟机内存到卸载出内存,包括

    加载-----链接-----初始化-----使用------卸载

    链接具体包括:验证-----准备-----解析

    3db5765d7d73f1b99f426f24f122c343.png

    加载:由类加载器执行,查找字节码并从这些字节码中创建一个Class对象。

    链接:验证类中的字节码;为静态域分配存储内存并赋予默认值;解析这个类创建的对其他类的所有引用。

    初始化:该类具有基类,则对其初始化,执行静态初始化和静态初始化块。

    类初始化的时机:程序中首次使用才初始化。

    首次主动使用:

    1.      创建类的实例

    2.      访问类的静态变量

    3.      调用类的静态方法

    4.      反射调用

    5.      初始化类的子类,如果父类为被初始化则先初始化父类

    6.      虚拟机启动时指定的启动类(包含main方法)虚拟机会先初始化该类

    类的初始化步骤:

    1,  没有被加载和链接的话就先进行加载连接。

    2,  有直接父类并且还没有初始化那就先初始化直接父类。

    3,  存在初始化语句,就按顺序依次执行初始化语句。(初始化语句包括静态语句和静态代码块)

    注:

    1.  如果是一个static final的编译器常量(常量池),就不需要对该类进行初始化就可以被读取,但是不是编译器常量对其访问将强制进行类的初始化。

    class A{

    public static final int b = 10;

    public static final int c = new Random().nextInt(10);

    static {

    System.out.println("A类被初始化");

    }

    }

    public class Test{

    public static void main(String[] args) {

    int i = A.b; // 不会导致初始化,因为b是一个编译时常量

    int ii = A.c; // 回导致初始化,c在编译时不能确定

    }

    }

    2.static域不是final的,那么访问它必须要进行链接和初始化。

    3.只有当访问的静态变量或方法是在当前类或接口中定义时,才认为是对类或接口的主动使用。

    interface A{

    int a = 10;

    }

    class AImp implements A{

    static {

    System.out.println("A类被初始化");

    }

    }

    public class Test{

    public static void main(String[] args) {

    int i = A.a; // 不会导致初始化,访问的变量不是当前类中定义的

    }

    }

    4.使用.class创建Class的引用时,不会自动的初始化。初始化被延迟到了对静态方法或者静态域的首次调用时才执行。

    class A{

    public static int b = 10;

    static {

    System.out.println("A类被初始化");

    }

    }

    public class Test{

    public static void main(String[] args) {

    Class class1 = A.class; // 没有输出

    int aa = A.b; // 这句会导致输出 A类被初始化

    try {

    Class class2 = Class.forName("A"); //注释掉上面两句 output: A类被初始化

    } catch (ClassNotFoundException e) {

    e.printStackTrace();

    }

    }

    }

    5. 通过数组定义引用类,不会触发此类的初始化。

    类中成员的初始化

    1.为类中变量赋初值在Java里面可以在定义类成员的地方为其赋值(c++里不能这样),也可以通过构造函数进行初始化,并且构造函无法阻止自动初始化也进行。

    class Test{

    int a;

    Test(){a = 10;}// a首先被置为0,然后变成7.

    }

    2.变量的初始化顺序取决于变量定义的顺序。他们在任何方法(包括构造函数)调用之前得到初始化。

    class A{

    public int i = 10;

    public A(){

    System.out.println("构造函数->" + i);

    i = 20;

    System.out.println("构造函数->" + i);

    }

    static {

    System.out.println("A类被初始化");

    }

    }

    public class Test{

    public static void main(String[] args) {

    A a = new A(); // 执行构造函数之前就饿比赋值成10了,执行构造函数后又被置为20

    // output :

    //A类被初始化

    //构造函数10

    //构造函数20

    }

    }

    3.静态数据的初始化,只占有一份内存区域。静态初始化只有在必要的时刻才会进行。必要的时刻指的是类被主动使用时。

    4.初始化顺序是先静态后非静态。前面讨论初始化过程只说静态语句和静态代码块,其实也会有非静态成员属性的初始化,并且是先初始化静态再初始化非静态的。不可能存在非静态成员初始化了而静态成员未被初始化的情况。

    一个奇怪的问题

    class Singleton{

    //private static Singleton singleton = new Singleton(); // 1

    public static int counter1;

    public static int counter2 = 0;

    private Singleton(){

    counter1++;

    counter2++;

    }

    private static Singleton singleton = new Singleton(); // 2

    public static Singleton getInstance(){

    return singleton;

    }

    }

    public class Test{

    public static void main(String[] args) {

    Singleton singleton = Singleton.getInstance();

    System.out.println("counter1 = " + singleton.counter1);

    System.out.println("counter2 = " + singleton.counter2);

    }

    }

    输出:

    放在位置1

    1 Singleton singleton =Singleton.getInstance();由于是调用该类的静态方法,因为检查还未加载,接下来会依次加载,链接,初始化。

    2 在链接的准备过程中singleton 为null  counter1为0 counter2为0

    3 在初始化过程,按顺序初始化

    3.1 初始化 private staticSingleton singleton = new Singleton();会执行构造函数,counter1为1,counter2为1

    3.2 初始化public static intcounter1; 其实没有初始化的值,因此还是之前的值为1

    3.3 初始化public static intcounter2 = 0; 将0赋值给counter2为0

    输出为 1 和 0

    counter1 = 1

    counter2 = 0

    放在位置2就很容易理解

    counter1 = 1

    counter2 = 1

    展开全文
  • Java字节代码的表现形式是字节数组(byte[])...这三个步骤中,对开发人员直接可见的是Java类的加载,通过使用Java类加载器(class loader)可以在运行时刻动态的加载一个Java类;而链接和初始化则是在使用Java类之前会...

    Java字节代码的表现形式是字节数组(byte[]),而Java类在JVM中的表现形式是java.lang.Class类的对象。一个Java类从字节代码到能够在JVM中被使用,需要经过加载、链接和初始化这三个步骤。这三个步骤中,对开发人员直接可见的是Java类的加载,通过使用Java类加载器(class loader)可以在运行时刻动态的加载一个Java类;而链接和初始化则是在使用Java类之前会发生的动作。本文会详细介绍Java类的加载、链接和初始化的过程。

    30a7c5911afbb374d46947f1a65ab014.png

    类加载的初始化阶段对类变量赋予正确的值。主要有两种初始化方式,一种是通过类变量初始化语句;一种是静态初始化语句。如下述代码所示,前者是类变量初始化语句,后者是静态初始化语句。

    public class Example1 {

    static int width;

    static int height = (int) (Math.random() * 2.0);

    static {

    width = (int) (3 * Math.random() * 5.0);

    }

    }

    所有的类变量初始化语句和静态初始化语句都被Java编译器收集在一起,放在一个特殊方法里。对于类而言,该方法称为类初始化方法,对于接口而言,该方法称为接口初始化方法。在Java class文件里,类和接口的初始化方法统一被称作为() 方法。并且这种方法只能被Java虚拟机调用,Java程序是无法调用的。

    ece148d47be6a0c3bbde8e0ae67de561.png

    Java类的初始化

    当一个Java类第一次被真正使用到的时候,JVM会进行该类的初始化操作。初始化过程的主要操作是执行静态代码块和初始化静态域。在一个类被初始化之前,它的直接父类也需要被初始化。但是,一个接口的初始化,不会引起其父接口的初始化。在初始化的时候,会按照源代码中从上到下的顺序依次执行静态代码块和初始化静态域。

    public class StaticTest {

    public static int X = 10;

    public static void main(String[] args) {

    System.out.println(Y); //输出60

    }

    static {

    X = 30;

    }

    public static int Y = X * 2;

    }

    在上面的代码中,在初始化的时候,静态域的初始化和静态代码块的执行会从上到下依次执行。因此变量X的值首先初始化成10,后来又被赋值成30;而变量Y的值则被初始化成60。

    3e8e532ef9a60046cc3d16e69334a4db.png

    类加载以及初始化的顺序是:类的静态成员初始化分配内存(有父类的先父类,然后自己)->然后main方法执行->类初始化{类非静态成员的初始化,然后执行构造器(有父类的先给父类的非静态成员初始化,然后父类的构造器)}

    展开全文
  • 类的加载过程1首先执行类中的静态代码块2初始化静态变量3最后new一个对象注意:如果一个类中有静态代码块非静态代码块在加载时首先执行静态代码块有多个时则按照放置顺序执行new对象实例时则会首先执行非静态代码...

    类的加载过程

    1首先执行类中的静态代码块

    2初始化静态变量

    3最后new一个对象

    注意:如果一个类中有静态代码块和非静态代码块

    在加载时首先执行静态代码块有多个时则按照放置顺序执行

    new对象实例时则会首先执行非静态代码块有多个时则按照顺序执行

    加载类和实例的区别

    加载类:只是为类的静态成员分配内存并初始化

    对象为nullint0char0booleanfalse

    new对象则为非静态成员分配内存

    packageClassLoader;

    //5.5加载类window

    classWindow{

    Window(){

    System.out.println("Window"+"("+")");

    }

    Window(intmask){

    System.out.println("Window"+"("+mask+")");

    }

    //5.6加载静态代码块加载完毕返回创建对象

    {

    //代码块在new一个对象时都会执行并且时先执行再调用构造函数

    System.out.println("loadclasswindow");

    }

    }

    //5.1加载House类

    classHouse{

    //5.2初始化成员变量d

    staticintd;

    booleanad;

    Windoww1=newWindow(1);

    //5.3按照顺序加载静态代码块并执行其中的方法

    static{

    System.out.println("first");

    }

    House(){

    System.out.println("House");

    //w3=newWindow(33);

    }

    Windoww2=newWindow(2);

    voidf(){

    System.out.println("f()");

    }

    Windoww3=newWindow(3);

    static{

    //5.4创建对象引起的window类的加载

    //5.7加载完毕后调用构造器创建对象

    Windowww=newWindow(100);

    //5.8继续初始化House类加载完毕返回

    System.out.println("ok");

    }

    }

    //类的加载完成两件事一完成对静态成员变量的初始化加载class文件

    二执行静态域但不执行静态方法

    //调用静态成员静态域引起类加载(加载时会执行static区域内的代码块)

    publicclassInitialiedAndNew{

    //3.初始化house

    staticHousehouse;

    //1.运行main方法加载InitialiedAndNew类先执行代码块再按照顺序初始化成员变量

    publicstaticvoidmain(String[]args){

    //4.执行main方法

    //5.调用构造器(静态创建对象首先5.1加载House类

    //5.9加载完毕调用构造器创建对象

    //Househ=newHouse();

    Classcls=Class.forName("ClassLoader.House");

    System.out.println("loadsuccessful");

    Househ=(House)cls.newInstance();

    //6.0执行赋值

    House.d=0;

    /newHouse();

    }

    static{

    System.out.println("house:");

    }

    //2.先执行static域代码

    static{

    System.out.println("loadclassInitialiedAndNew");

    System.out.println("houseinitialieis"+house);

    }

    }

    展开全文
  • 1.前言java是跨平台语言,主要是因为它的java...一个类在JVM中被实例化成一个对象,需要经历三个过程:加载、链接和初始化。2.加载通过读取字节码二进制.class文件将类加载到内存,从而达到类的从硬盘上到内存上的一...
  • 本文实例讲述了Java类的加载连接和初始化。分享给大家供大家参考,具体如下:一 点睛1 类加载当程序主动使用某个类时,如果该类还未被加载到内存中,系统会通过加载、连接、初始化三个步骤来对该类进行初始化,如果...
  • 请注意以下内容,很明显类加载和初始化是两种不同机制.As a side point, please note the distinction between class loading andclass initialization: only the latter’s occurrence is preciselyspecified by ...
  • 初始化这个类的顺序是: 先按顺序初始化静态方法属性,若静态方法中调用了其他方法,那么这些方法的初始化顺序也将紧跟在调用他的这个静态方法之后,并且会执行方法的内容。静态数据初始化完毕后,再根据 main()...
  • 自己写一遍加深印象类的加载加载就是通过指定的类全限定名,获取此类的二进制字节流(可以是clazz文件或者直接内存读取或者远程网络,jar包等),然后将此二进制字节流转化为方法区的数据结构,在内存中生成一个代表这...
  • 为什么说Java是跨平台语言Java语言运行环境是在Java虚拟机中。 Java虚拟机消除了各个平台之间差异,只要操作系统平台下安装了Java虚拟机,那么使用...JVM虚拟机启动和加载类过程下面以一个简单的java程序,分...
  • 一、类初始化过程1、一个要创建实例需要先创建和加载(1) main方法所在的类需要先加载和实例化2、一个子类要初始化,需要先初始化父类3、一个类初始化就是执行方法(1) () 方法由静态变量显示赋值代码静态代码块...
  • 第一段:class A{public A(){this.list();}public void list(){System.out.println("in a list..");}}class B extends A{private ... //这里会调用list,是在还没构造结束时候就调用了,但这里不会错public static...
  • 本节将会详细介绍类加载、连接和初始化过程中每个细节。JVM 和类当调用 java 命令运行某个 Java 程序时,该命令将会启动一个 Java 虚拟机进程,不管该 Java 程序有多么复杂,该程序启动了多少个线程,它们都处于该...
  • 本节将会详细介绍类加载、连接和初始化过程中每个细节。JVM 和类当调用 java 命令运行某个 Java 程序时,该命令将会启动一个 Java 虚拟机进程,不管该 Java 程序有多么复杂,该程序启动了多少个线程,它们都处于该...
  • 主要介绍了Java类的加载连接和初始化,结合具体实例形式分析了java类的加载、连接、初始化相关原理与实现技巧,需要的朋友可以参考下
  • Java类何时以及如何加载和初始化?通过使用下面简单示例可以清楚地说明。说“上课”是什么意思?首先将C / C ++编译为本机代码,然后在编译后需要链接步骤。链接作用是组合来自不同位置源文件并形成可执行程序...
  • 类的初始化过程类在使用之前会经过加载、连接、初始化三个步骤。加载将类的 class 文件读入内存,并为之创建一个 java.lang.Class 对象。连接连接又可以分为三个子步骤: 连接:检验被加载的类是否有正确的内部结构...
  • java类加载的时机触发类的初始化的条件 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载,验证,准备,解析,初始化,使用,卸载7个阶段。其中验证、准备、解析三个部分统称为连接。...
  • Java类何时以及如何加载和初始化?通过使用下面简单示例可以清楚地说明。说“上课”是什么意思?首先将C / C ++编译为本机代码,然后在编译后需要链接步骤。链接作用是组合来自不同位置源文件并形成可执行程序...
  • 对象初始化过程:1.首先,初始化父类中静态成员变量静态代码块,按照在程序中出现顺序初始化;2.然后,初始化子类中静态...Java类加载机制1.概述Class文件由类装载器装载后,在JVM中将形成一份描述Class...
  • JAVA类加载和初始化

    2018-03-25 15:44:00
    JAVA类的加载和初始化 一、类的加载和初始化过程 JVM将类的加载分为3个步骤: 1、加载(Load):class文件创建Class对象。 2、链接(Link) 3、初始化(Initialize) 其中 链接(Link)又分3个步骤,如下图...
  • 最近在阅读孙卫琴的java面向对象一书中,看到对java类的初始化和加载中的论述比较系统,故笔记之1)类的初始化,JAVA在初始化一个类时,以下步骤 A 假如类存在直接的父类,并且这个父类还没有初始化,则先初始化...
  • java 类初始化和加载顺序 成员变量 (按照申明顺序初始化)>> Constructor 方法(生成对象)>> @Autowired (注入对象)>> @PostConstruct (初始化方法,依赖于注入)
  • 考察Java 类的初始化的顺序,主要为Java 类加载器在加载类时候的两个阶段:准备 初始化。 题目: public class StaticTest { public static void main(String[] args) { staticFunction();
  • @java类的加载顺序 Java类的加载顺序 父类静态代变量、 父类静态代码块、 子类静态变量、 子类静态代码块、 父类非静态变量(父类实例成员变量)、 父类构造函数、 子类非静态变量(子类实例成员变量)、 子类构造...
  • 3   1、什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在...类加载器并不需要等到某个类被...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,771
精华内容 3,108
关键字:

java类的初始化和类加载

java 订阅