首页 > 编程语言 >Java类初始化、变量初始化

Java类初始化、变量初始化

时间:2022-12-08 13:23:24浏览次数:62  
标签:初始化 Java 变量 int field static final

Java类初始化、变量初始化

摘自:https://blog.csdn.net/mocas_wang/article/details/109956014

基础知识

  • Java常量, final 修饰,值被设定后不能再被修改
  • 静态变量里, static 修饰,顾名思义,无须创建对象,便可在内存中申请一个存储空间进行存储
  • 成员变量, 也称实例变量,它随着当前对象的建立而建立,随着对象的销毁而销毁,存在于对象所在的堆内存中
  • 构造器,创建class对象时执行
  • 静态初始化块 ,执行优先级高于非静态的初始化块,它会在对象装载到 jvm的时候执行一次,执行完成便销毁,只能初始化 static 修饰的变量
  • 非静态初始化块,执行的时候如果有静态初始化块,先执行静态初始化块再执行非静态初始化块,在每个对象生成时都会被执行一次,它可以初始化类的实例变量。但它会在构造函数执行之前被执行。

类的初始化顺序

Java中类初始化顺序,依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。。

变量的初始化问题

类成员变量初始化

对于类的成员变量。不管程序有没有显示的初始化,Java 虚拟机都会先自动给它初始化为默认值。

规则为:

1、整数类型(byte、short、int、long)的基本类型变量的默认值为0。

2、单精度浮点型(float)的基本类型变量的默认值为0.0f。

3、双精度浮点型(double)的基本类型变量的默认值为0.0d。

4、字符型(char)的基本类型变量的默认为 “/u0000”。

5、布尔性的基本类型变量的默认值为 false。

6、引用类型的变量是默认值为 null。

7、数组引用类型的变量的默认值为 null。春关键数组变量的实例后,如果没有没有显示的为每个元素赋值,Java 就会把该数组的所有元素初始化为其相应类型的默认值。

局部变量初始化

局部变量声明以后,Java 虚拟机不会自动的为它初始化为默认值。因此对于局部变量,必须先经过显示的初始化,才能使用它。

如果编译器确认一个局部变量在使用之前可能没有被初始化,编译器将报错。

那么,加了修饰的java成员变量是如何初始化的呢?在何时?在程序中的什么位置?

public class TestC {
	/*
	 * 定义成员变量
	 * 尾数为1表示定义时进行初始化赋值
	 * 尾数为2表示在代码块中进行初始化赋值
	 * 尾数为3表示在构造函数中进行初始化赋值
	 * 尾数为4表示在静态代码块中进行初始化赋值
	 * 尾数为5表示不初始化赋值
	 */
	/*
	 * 普通成员变量 
	 */
	int field_a1 = 5;
	int field_a2;
	int field_a3;
	//报错:不能再静态代码块中使用非静态变量。 Cannot make a static reference to the non-static field field_a4
	//int field_a4;
	int field_a5;
	/*
	 * final 成员变量
	 */
	final int  field_b1 = 5;
	final int  field_b2;
	final int  field_b3;
	//报错:不能再静态代码块中使用非静态变量。Cannot make a static reference to the non-static field field_b4
	//final int  field_b4;
	//报错:未初始化 。The blank final field field_b5 may not have been initialized
	//final int  field_b5;
	/*
	 * static成员变量
	 */
	static int field_c1 = 5;
	static int field_c2;
	static int field_c3;
	static int field_c4;
	static int field_c5;
	/*
	 * static final 成员变量
	 */
	static final int field_d1 = 5;
	//报错:未初始化 。The blank final field field_d2 may not have been initialized
	//static final int field_d2;
	//报错:未初始化 。The blank final field field_d3 may not have been initialized
	//static final int field_d3;
	static final int field_d4;
	//报错:未初始化 。The blank final field field_d5 may not have been initialized
	//static final int field_d5;
	
	//代码块
	{
		
		field_a2 = 5;
		field_b2 = 5;
		field_c2 = 5;
		//field_d2 = 5;
	}
	
	//静态代码块
	static{
		//field_a4 = 5;
		//field_b4 = 5;
		field_c4 = 5;
		field_d4 = 5;
	}
	
	//构造函数
	public TestC(){
		field_a3 = 5;
		field_b3 = 5;
		field_c3 = 5;
		//field_d3 = 5;
		
	}
}

然后我们对这个程序生成的.class文件进行反编译,看看他是如何运行的。

下面是TestC.jad文件。反编译文件

public class TestC
{

    public TestC()
    {
        field_a1 = 5;
        field_a2 = 5;
        field_c2 = 5;
        field_a3 = 5;
        field_c3 = 5;
    }

    int field_a1;
    int field_a2;
    int field_a3;
    int field_a5;
    final int field_b1 = 5;
    final int field_b2 = 5;
    final int field_b3 = 5;
    static int field_c1 = 5;
    static int field_c2;
    static int field_c3;
    static int field_c4 = 5;
    static int field_c5;
    static final int field_d1 = 5;
    static final int field_d4 = 5;

}
  • 对于不加修饰的普通成员变量,无论我们在什么地方对其进行初始化赋值,系统都会默认在构造函数中进行赋值。
  • 对于final变量,无论我们在什么地方进行赋值,系统会默认final变量是在类中进行初始化。
  • 对于static,系统会根据我们的需求,而在不同位置进行初始化。

通过报错,我们可以发现。

  • final变量必须进行初始化。否则就会报编译错误。The blank final field field_d5 may not have been initialized
  • static成员变量的初始化发生在类被类加载器(classLoader)加载的时候系统会对没有初始化的静态成员变量在静态区进行默认赋值。
  • 普通成员变量的初始化发生在JVM为类生成实例开辟空间的时候进行默认初始化赋值。

总结

final修饰的变量必须显性进行初始化。初始化有三种方式:

  1. 直接初始化

  2. 动态代码块

  3. 构造函数

  • 如果一个变量既被final修饰又被static修饰,那么这个变量一定要被初始化(满足final特性),另外要么直接初始化要么在静态代码块中进行初始化(满足static特性)。
  • final修饰的变量的初始化先于static修饰的变量,static修饰的变量先于普通变量的初始化。
  • 如果是final级别的,那么虽然也是根据代码次序的前后顺序进行初始化,但是它是在编译阶段进行宏替换,即在编译阶段就知道了值,因此在加载运行阶段对这一先后顺序完全感知不到。
  • 但是如果是static级别的,代码的先后顺序会造成程序运行结果的不同。因为它们都是在加载进行的时候进行初始化的。

归结如下:

  1. final修饰的变量在编译阶段完成
  2. static修饰的变量在一个静态代码块中进行初始化
  3. 普通变量在构造函数中进行初始化

标签:初始化,Java,变量,int,field,static,final
From: https://www.cnblogs.com/zhangj9/p/16965797.html

相关文章

  • 通俗的英文指南——Javascript的原型
    ​​http://www.w3cplus.com/js/a-plain-english-guide-to-javascript-prototypes.html​​​当我开始学习JavaScript的对象模型时,第一反应就是难以......
  • (转)Java中有关Null的9件事
    对于Java程序员来说,null是令人头痛的东西。时常会受到空指针异常(NPE)的骚扰。连Java的发明者都承认这是他的一项巨大失误。Java为什么要保留null呢?null......
  • java springboot 大文件分片上传处理
    ​  1 背景用户本地有一份txt或者csv文件,无论是从业务数据库导出、还是其他途径获取,当需要使用蚂蚁的大数据分析工具进行数据加工、挖掘和共创应用的时候,首先要将本地......
  • JUC12 java并发编程容器
    0.java容器类​​JAVA容器详解_诗酒趁年华527的博客​​Java容器详解-_情书-​​一文秒懂java容器大全-知乎​​Collection:List,Set,QueueMap:2.java并发容器......
  • Java对接工商银行聚合支付(无界面)(微信小程序支付&回调验签&退款)
    写在前面最近两天整合对接了工商银行的聚合支付通道,目前已上线运行。踩了一些坑,以此记录供网友分享。此文对接产品的主要是【线上POS聚合消费下单接口(无界面)】准备工作......
  • java-net-php-python-sceatch在线学习系统2019演示录像计算机毕业设计程序
    OverridetheentrypointofanimageIntroducedinGitLabandGitLabRunner9.4.Readmoreaboutthe extendedconfigurationoptions.Beforeexplainingtheav......
  • 四、程咬金——JavaScript基础
     一、前言Ajax,异步JavaScript和XML,前面已经解释过,所以Ajax的学习还包含JavaScript和XML,这里我们先看JavaScript,而JavaScript实际上又是包含JavaScript语法和HTMLDOM即文档......
  • 《悟透javascript》学习笔记
    《悟透javascript》学习笔记 一、         前言 二、         回归简单、基本类型 三、         表演、似类却不是类 四、      ......
  • 《悟透javascript》学习笔记:X、深入继承
    引言      JavaScript不是按面向对象的思想设计的程序语言,所以它不具备像现有的面向对象的语言那样的功能,但是面向对象的思想是如此的深入人心,以至于JavaScript也削......
  • 再读《悟透javascript》之五、五子棋
    前言     五子棋是个很有趣的游戏,在用javascript开发之后,我发现其实ai算法才是最难的,这里的ai算法是直接借鉴自其它的ai算法。  代码如下:<htmlxmlns="http://www.w3......