Java类的初始化、变量的初始化

Java类的初始化、变量的初始化


知识点

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

类的初始化顺序

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


Java变量的初始化问题探究


对于java的变量,我们知道有成员变量局部变量。

关于他们的初始化,基本上所有书上都会写。成员变量,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成员变量是如何初始化的呢在何时?在程序中的什么位置?

下面看个小程序。

[java] view plaincopy
  1. public class TestC {  
  2.     /* 
  3.      * 定义成员变量 
  4.      * 尾数为1表示定义时进行初始化赋值 
  5.      * 尾数为2表示在代码块中进行初始化赋值 
  6.      * 尾数为3表示在构造函数中进行初始化赋值 
  7.      * 尾数为4表示在静态代码块中进行初始化赋值 
  8.      * 尾数为5表示不初始化赋值 
  9.      */  
  10.     /* 
  11.      * 普通成员变量  
  12.      */  
  13.     int field_a1 = 5;  
  14.     int field_a2;  
  15.     int field_a3;  
  16.     //报错:不能再静态代码块中使用非静态变量。 Cannot make a static reference to the non-static field field_a4  
  17.     //int field_a4;  
  18.     int field_a5;  
  19.     /* 
  20.      * final 成员变量 
  21.      */  
  22.     final int  field_b1 = 5;  
  23.     final int  field_b2;  
  24.     final int  field_b3;  
  25.     //报错:不能再静态代码块中使用非静态变量。Cannot make a static reference to the non-static field field_b4  
  26.     //final int  field_b4;  
  27.     //报错:未初始化 。The blank final field field_b5 may not have been initialized  
  28.     //final int  field_b5;  
  29.     /* 
  30.      * static成员变量 
  31.      */  
  32.     static int field_c1 = 5;  
  33.     static int field_c2;  
  34.     static int field_c3;  
  35.     static int field_c4;  
  36.     static int field_c5;  
  37.     /* 
  38.      * static final 成员变量 
  39.      */  
  40.     static final int field_d1 = 5;  
  41.     //报错:未初始化 。The blank final field field_d2 may not have been initialized  
  42.     //static final int field_d2;  
  43.     //报错:未初始化 。The blank final field field_d3 may not have been initialized  
  44.     //static final int field_d3;  
  45.     static final int field_d4;  
  46.     //报错:未初始化 。The blank final field field_d5 may not have been initialized  
  47.     //static final int field_d5;  
  48.       
  49.     //代码块  
  50.     {  
  51.           
  52.         field_a2 = 5;  
  53.         field_b2 = 5;  
  54.         field_c2 = 5;  
  55.         //field_d2 = 5;  
  56.     }  
  57.       
  58.     //静态代码块  
  59.     static{  
  60.         //field_a4 = 5;  
  61.         //field_b4 = 5;  
  62.         field_c4 = 5;  
  63.         field_d4 = 5;  
  64.     }  
  65.       
  66.     //构造函数  
  67.     public TestC(){  
  68.         field_a3 = 5;  
  69.         field_b3 = 5;  
  70.         field_c3 = 5;  
  71.         //field_d3 = 5;  
  72.           
  73.     }  
  74. }  

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

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

[java] view plaincopy
  1. public class TestC  
  2. {  
  3.   
  4.     public TestC()  
  5.     {  
  6.         field_a1 = 5;  
  7.         field_a2 = 5;  
  8.         field_c2 = 5;  
  9.         field_a3 = 5;  
  10.         field_c3 = 5;  
  11.     }  
  12.   
  13.     int field_a1;  
  14.     int field_a2;  
  15.     int field_a3;  
  16.     int field_a5;  
  17.     final int field_b1 = 5;  
  18.     final int field_b2 = 5;  
  19.     final int field_b3 = 5;  
  20.     static int field_c1 = 5;  
  21.     static int field_c2;  
  22.     static int field_c3;  
  23.     static int field_c4 = 5;  
  24.     static int field_c5;  
  25.     static final int field_d1 = 5;  
  26.     static final int field_d4 = 5;  
  27.   
  28. }  

看到这里我们就很有清晰的思路了。

对于不加修饰的普通成员变量,无论我们在什么地方对其进行初始化赋值,系统都会默认在构造函数中进行赋值。

对于final变量,无论我们在什么地方进行赋值,系统会默认final变量是在类中进行初始化

对于static,系统会根据我们的需求,而在不同位置进行初始化。


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

final变量必须进行初始化。否则就会报编译错误。The blank final field field_d5 may not have been initialized

static成员变量的初始化发生在类被类加载器(classLoader)加载的时候系统会对没有初始化的静态成员变量在静态区进行默认赋值。

普通成员变量的初始化发生在JVM为类生成实例开辟空间的时候进行默认初始化赋值


参考博文:https://blog.csdn.net/wlcw16/article/details/8506846


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 多线程 —— wait 与 notify

引言 认识一下 Object 类中的两个和多线程有关的方法:wait 和 notify。 wait,当前线程进入 WAITING 状态,释放锁资源。 notify,唤醒等待中的线程,不释放锁资源。 一、使用 wait-notify 实现一个监控程序 实现一个…

重写equal()时为什么也得重写hashCode()之深度解读equal方法与hashCode方法渊源

重写equal()时为什么也得重写hashCode()之深度解读以及equal方法与hashCode方法渊源转载自:http://blog.csdn.net/javazejian/article/details/51348320 今天这篇文章我们打算来深度解读一下equal方法以及其关联方法hashCode(),我们准备从以下几点入手分…

Java8————Optional

引言 Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。 Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进…

数据库的几种去重方法总结

一、数据库中的去重操作(删除数据库中重复记录的SQL语句)主要有三种方法 (1)、rowid方法 (2)、group by 方法 (3)、distinct方法 1、用rowid方法 根据Oracle带的rowid属性&#xff0…

Java8————日期时间 API

引言 Java 1.0 中引入了 Date 类,Java 1.1 中引入了 Calendar ,Java 8 中引入了java.time API ,这是 Java 非常吸引人的一次对时间日期的升级。它修正了过去的缺陷,同时也清晰易用。在 Java 8 引入time api 中,Instan…

问题反馈信息处理平台开发过程

问题反馈信息处理平台开发过程 “问题反馈信息处理平台”是一个将用户反馈上来的出错信息进行处理和收集的一个平台。 这个项目主要都是在实习的时候由我一个人进行开发,我导师在旁边进行指导完成的。 该项目的技术架构主要是: 前端主要基于Vue框架的…

Java8————Base64

Base64? Base64是一种用64个字符来表示任意二进制数据的方式。 对于二进制文件如图片、exe、音频、视频等,包含很多无法显示和打印的字符,如果希望能够通过记事本这样的文本处理软件处理二进制数据,就需要一个二进制转字符串的转…

大众点评后端项目解析

restful Api是一种设计风格: 启动前端项目:在前端项目根目录 npm install:加载依赖包 npm run mock:提供模拟数据的接口,前端脱离于后台;start /b npm run mock(于后台运行) npm…

Java中类及方法的加载顺序

代码展示 请运行下面代码,查看运行结果,并带着问题,尝试第二次debug程序。 class A {private static int numA;private int numA2;static {System.out.println("A的静态字段 : " numA);System.out.println("A的静态代码块…

新手入门教程-------Spring Boot中集成RabbitMQ

AMQP:是Advanced Message Queuing Protocol的简称,高级消息队列协议,是一个面向消息中间件的开放式标准应用层协议。 定义了以下特性: 消息方向消息队列消息路由(包括:点到点和发布-订阅模式)可…

Java 多线程 —— ReentrantLock 与 Condition

引言 ReentrantLock 是 JUC 下的一个功能强劲的锁工具,支持公平锁、非公平锁,以及多等待队列的 Condition 。 也常常被称为“手动锁”。本篇博客主要分析它的使用方法以及 Condition 实现的一个生产者消费者模式。 一、可替代 synchronized 的手动锁 …

Rabbitmq+Springboot设计秒杀应用

秒杀业务的核心是库存处理,用户购买成功后会进行减库存操作,并记录购买明细。当秒杀开始时,大量用户同时发起请求,这是一个并行操作,多条更新库存数量的SQL语句会同时竞争秒杀商品所处数据库表里的那行数据&#xff0c…

Java8————Stream API

引言 Java8 加入了java.util.stream包,这个包中的相关API将极大的增强容器对象对元素的操作能力。 它专注于对集合对象进行各种便利、高效的聚合操作,或大批量数据处理。 Stream API借助于同样新出现的Lambda表达式,极大的提高了编程效率和…

MySQL数据库知识点总结

数据库: 数据库索引的好处:索引是对数据库表中的一个或多个列的值进行排序的结构,这样检索或者查询某条记录的时候就不在是顺序查找,而是使用特定的查找方式进行查找,如通过二分查找或者是hash值来查找,提高…

Java8 函数式对齐约定————Eclipse自定义代码风格

引言 Java8 的函数式代码风格在Stream的使用上尤为突出。尽管我们可以通过连续调用函数完成一系列操作,但是其可读性并不能保证,还需要有与之相辅的Code Style。例如,请尝试阅读下面两段完全相同的代码: 未遵守约定格式&#xf…

Java核心篇之JVM--day3

Java核心篇之JVM--day3 Java JVM详解--通俗易懂教程 JVM:Java虚拟机的简称。 谈到JVM,通常会聊到三个问题: 1. 什么时候触发Java GC? 2. 对什么东西进行Java GC? 3. 如何进行Java GC? 首先解决第…

Java8————Lambda表达式(一)

本博客翻译自官方教程《Syntax of Lambda Expressions》 Lambda表达式的语法 一个Lambda表达式由以下部分构成: 1、圆括号内的一个由逗号分隔的参数列表。 interface CheckPerson {boolean test(Person p); } CheckPerson.test方法包含一个参数,p&a…

使用springboot来实现WebLog

使用websocket技术实时输出系统日志到浏览器端,实现WebLog boot-websocket-log: spring boot系统中使用websocket技术实时输出系统日志到浏览器端,因为是实时输出,所有第一时间就想到了使用webSocket,而且在spring boot中&#…

Java8————Lambda表达式(二)

译者注:文中内容均来自于官方教程《Lambda Expressions》,但是由于英汉语言的差异,部分语句官方描述过于冗余,因此译者根据通常状况的理解做了微调,但不会影响表达的含义。比如: 原文:You want …

设计模式---观察者模式介绍与理解

设计模式---观察者模式介绍与理解: 观察者模式原理:类似于定牛奶业务 1. 奶站,subject:登记注册,移除,通知(register,remove,notify) 2. 用户,…