首页 > 编程知识 正文

构造函数 静态代码块,构造方法 静态代码块

时间:2023-05-06 05:17:22 阅读:184270 作者:3770

近期做牛客网的Java开发笔试题,发现这类型的题目较多,很容易混淆,特将相关概念和相关示例整理如下,供大家参考^_^

1. 静态代码块在类加载时即运行,而且只运行一次,并且优先于各种代码块以及构造函数运行。如果一个类中有多个静态代码块,会按照书写顺序依次执行。静态代码块不能访问普通变量(普通变量只能通过对象来调用)。

2. 构造代码块在创建对象时被调用,每次创建对象都会调用一次,但是优先于构造函数执行。如果不实例化对象,构造代码块不会执行。如果存在多个构造代码块,则执行顺序按照代码顺序依次执行(多个构造函数情况下,创建对象时传入的参数不同则初始化对应的构造函数)。

格式如下:

public class StaticTest { static //静态代码块 { System.out.println("静态代码块"); } {//构造代码块 System.out.println("构造代码块"); }}

3.构造函数不能被直接调用,必须通过new运算符在创建对象时才会自动调用;而一般的方法是在程序执行到它的时候被调用的;当定义一个类的时候,通常情况下都会显示该类的构造函数,并在函数中指定初始化的工作也可省略,不过Java编译器会提供一个默认的构造函数,此默认构造函数是不带参数的。一般的方法则不具有这一特点。

格式如下:

public class test{ public test() { System.out.println("无参构造方法"); } public test(String a) { System.out.println("有参构造方法"); } .....}

程序执行顺序:静态代码块>构造代码块>构造函数>普通代码块

对象的初始化顺序:

1)首先执行父类静态的内容;

2)接着执行子类的静态的内容;

3)执行父类构造代码块;

4)执行父类的构造方法;

5)执行子类构造代码块;

6)执行子类的构造方法。

总结:静态代码块内容先执行(先父类,再子类),接着执行父类构造代码块和构造方法,之后执行子类构造代码块和构造方法。

示例如下:

public class StaticTest{ public static void main(String args[]) { staticFunction(); } static StaticTest st = new StaticTest(); static //静态代码块 { System.out.println("1"); } StaticTest() //构造函数 { System.out.println("3"); System.out.println("a="+a+" b="+b); } public static void staticFunction() { System.out.println("4"); } { //构造代码块 System.out.println("2"); } int a=100; static int b=112;}

输出结果:
2
3
a=100 b=0
1
4

解析:类初始化时首先初始化静态内容(静态变量,静态代码块,按顺序执行)。静态引用变量st (static StaticTest st = new StaticTest();)引用的是本类的实例,因此在实例化st变量时,将实例初始化嵌入到静态初始化中。因为这一句放在静态初始化的开头,所以static int b=112没有被调用,输出的b=0,同时,输出1也在2和3后面。在对象实例化时,即为普通成员变量分配内存,再执行构造函数,所以a的值为100。

public class Test { private int number=0; static{ System.out.println("静态代码块执行!"); } { System.out.println("构造代码块执行!"); number=1; } public Test(){ System.out.println("构造方法执行!"); System.out.println(number); } public static void main(String[] args) { System.out.println("---------"); Test test = new Test(); System.out.print("number is: "+test.number); }}

 运行结果:

静态代码块执行!

---------

构造代码块执行!

构造方法执行!

1

number is: 1

解析:类初始化过程中,首先初始化静态内容(静态变量,静态代码块,并按顺序执行)。静态代码块先执行,输出“静态代码块执行!”。接着执行静态方法main中的内容,所以输出“---------”,对象实例化的时候,首先执行构造代码块,再执行构造函数,依次输出里面的内容。

public class JDTest01 { public static void main(String[] args) { System.out.println(Test2.a); }}class Test2{ public static final String a = new String("JD"); static { System.out.print("OK"); }}/*输出结果:OKJD*/ public class JDTest02 { public static void main(String[] args) { System.out.println("A"); new JDTest02(); new JDTest02(); } public JDTest02() { System.out.println("B"); } { System.out.println("C"); } static { System.out.println("D"); }}/*输出结果:DACBCB*/

4.static的作用:

一些频繁使用的内容,如果每次使用都重新new一下,这个开销可能会很高,如果使用static,将会一直放在内存中,想用直接调用即可,无需重新new一块空间初始化数据。那么static就是为了实现一个系统的缓存作用,其生命周期直到应用程序退出结束。

这说明,static修饰的类成员,在程序运行过程中,只需要初始化一次即可,不会进行多次的初始化。

主要有四种用法:

1).用来修饰成员变量,将其变为类的成员,从而实现所有对象对于该成员的共享;

2).用来修饰成员方法,将其变为类方法,可以直接使用“类名.方法名”的方式调用,常用于工具类;

3).静态块用法,将多个类成员放在一起初始化,使得程序更加规整,其中理解对象的初始化过程非常关键;

4).静态导包用法,将类的方法直接导入到当前类中,从而直接使用“方法名”即可调用类方法,更加方便。

static可以修饰:方法,属性,代码段,内部类(静态内部类或嵌套内部类)

5.final主要四种用法

1).  用来修饰数据,包括成员变量和局部变量,该变量只能被赋值一次且它的值无法被改变。对于成员变量来讲,我们必须在声明时或者构造方法中对它赋值;

2).  用来修饰方法参数,表示在变量的生存期中它的值不能被改变;

3).  修饰方法,表示该方法无法被重写;

4).  修饰类,表示该类无法被继承。

final可以修饰:属性,方法,类,局部变量(方法中的变量)

Static final:同时使用static和final修饰的成员在内存中只占据一段不能改变的存储空间。

6.成员变量与局部变量的区别

1).在类中位置不同;成员变量:在类中方法外。局部变量:在方法定义中或者方法声明上。

2).在内存中的位置不同;成员变量:在堆内存。  局部变量:在栈内存。

3).生命周期不同;成员变量:随着对象的创建而存在,随着对象的消失而消失。 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失。

4).初始化值不同;成员变量:有默认值初始化。局部变量:没有默认值初始化,必须定义,赋值,然后才能使用。

另外,局部变量名称可以和成员变量名称一样,在方法中使用的时候,采用的是就近原则。

public class JDTest03 { public static void main(String[] args) { System.out.println(B.c);//直接使用类名调用静态变量 }}class A{ static { System.out.print("A"); }}class B extends A{ static { System.out.print("B"); } public final static String c = "C";}/*输出结果:C*/

详细解析请参见(JVM规范中初始化类的5种情况(有且仅有) ):https://blog.csdn.net/m0_37568814/article/details/82906889

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。