Java的静态块和初始化块分别何时执行?有啥区别?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java的静态块和初始化块分别何时执行?有啥区别?相关的知识,希望对你有一定的参考价值。
静态初始化块:当类第一次加载时执行。
非静态初始化块:非静态初始化块会在构造函数执行时,且在构造函数主体代码执行之前被执行。
区别如下:
1、执行次数不同
静态块只执行一次,初始化块可以执行多次。
2、作用不同
静态初始化块仅能初始化类变量,即static修饰的数据成员。
非静态初始化块可以初始化类的实例变量。
扩展资料:
使用Java静态代码块注意事项:
1、它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数的。
2、静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。
3、静态代码块中的变量是局部变量,与普通函数中的局部变量性质没有区别。
4、一个类中可以有多个静态代码块。
5、对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。
参考技术A 把下面这个问题搞懂,执行顺序的问题就差不多都搞懂了父类和子类中都要静态代码块,非静态代码块,构造方法时。
初始化子类对象时,调用的顺序是
调用顺序:父类静态,子类静态,父类非静态,父类构造,子类非静态,子类构造 参考技术B 静态块在类第一次加载时执行。初始化块在调用构造方法是执行。
静态块只执行一次,初始化块可以执行多次。
建议看看《Java编程思想》中初始化相关的类容,讲解的很清楚。 参考技术C 静态代码块只初始化一次是相对于类而言。初始化是针对对象而言的 参考技术D 静态块在第一个对象创建时运行
初始化块在每个对象创建时运行
区别是静态块只执行一次,操作的内存在静态区
初始化块每个对象构造时都需要执行一次,操作的内存在用户区本回答被提问者采纳
java中的静态代码块、代码块、构造器的执行顺序是怎样呢,这三者有啥作用呢
先说执行顺序:我们在new一个对象时,如果类还没加载,就需要先将类加载到内存,此时就会执行静态代码块,在创建对象时,是先执行代码块,然后执行构造器。所以静态代码块、代码块、构造器的执行顺序是:静态代码块→代码块→构造器。
再说作用:静态代码块是用于初始化类的(在加载类时执行,只执行一次),代码块是用于初始化对象的(在创建对象时执行,每次创建对象时都执行),构造器是用于创建对象的。
class T
private static final String msg = "this is a test class!";
private static int version = 1;
static
version = 2;
desc = "class T";
private static String desc = “T is a test Class”;
private int age = 2;
age = 10;
name = "panda";
public T()
age = 12;
name = "foxli";
private String name = "micky";
类T,存在静态域version和desc,实例域age和name。
类中,存在静态代码块static以及实例化代码块和默认的构造方法。
------------------------------------------------------------------------------------------------------------
先来说一下类型初始化方法<clinit>:
JVM通过Classload进行类型加载时,如果在加载时需要进行类型初始化操作时,则会调用类型的初始化方法。类型初始化方法主要是对static变量进行初始化操作,对static域和static代码块初始化的逻辑全部封装在<clinit>方法中。
java.lang.Class.forName(String name, boolean initialize,ClassLoader loader),其中第二个参数就是是否需要初始化。
Java类型初始化过程中对static变量的初始化操作依赖于static域和static代码块的前后关系,static域与static代码块声明的位置关系会导致java编译器生成<clinit>方法打字节码。
由上例子,T类型的类型初始化方法<clinit>最后编译出来的字节码顺序大概是这样的:
T.<clinit>
private static int version;
private static String desc;
version = 1;
version = 2;
desc = "class T";
desc = "T is a test Class";
类型的初始化方法<clinit>只在该类型被加载时才执行,且只执行一次。
-------------------------------------------------------------------------------------------------------------
接下来说一下对象实例化方法<init>:
Java对象在被创建时,会进行实例化操作。该部分操作封装在<init>方法中,并且子类的<init>方法中会首先对父类<init>方法的调用。
Java对象实例化过程中对实例域的初始化赋值操作全部在<init>方法中进行,<init>方法显式的调用父类的<init>方法,实例域的声明以及实例初始化语句块同样的位置关系会影响编译器生成的<init>方法的字节码顺序,<init>方法以构造方法作为结束。
由上例子,T对象的对象实例化方法<init>最后编译出来的字节码顺序大概是这样的:
T.<init>
int age;
String name;
this.age = 2;
this.age = 10;
this.name = "panda";
this.name = "micky";
this.age = 12;
this.name = "foxli";
对象实例化方法<init>以构造方法作为结束。当前并没有考虑存在父类的情况,如果存在,<init>方法首先会调用父类的<init>方法。
-------------------------------------------------------------------------------------------------------------
PS:这里面的msg称为编译时常量,他不再<clinit>方法中出现。
其中<clinit>方法在javap命令中没有显示,javap输出的static就是<clinit>方法。 参考技术B 静态代码块->构造器->代码块
以上是关于Java的静态块和初始化块分别何时执行?有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章