Java類中字段可以不賦予初始值的原因分析
Java類中字段可以不賦予初始值的原因
Java虛擬機(jī)會對類的實(shí)例對象進(jìn)行分配內(nèi)存,在分配內(nèi)存后,會將內(nèi)存空間(除了對象頭)全部初始化為零值。這就保證了,在類的定義過程中,不給字段賦初始值,實(shí)例對象也能有初始值。
下面是在Java類中各字段的初始值
字段 | 默認(rèn)初始值 |
對象 | null |
數(shù)值(byte,short,int,long,float,double) | 0或0.0 |
boolean | false |
char | \u0000(輸出出來是空值) |
class Solution { private static char c; private static int i; private static long l; private static float f; private static double d; private static String s; private static boolean bl; private static byte b; public static void main(String[] args) { System.out.println(c == '\u0000'); System.out.print(c); System.out.println(i); System.out.println(l); System.out.println(f); System.out.println(d); System.out.println(s); System.out.println(bl); System.out.println(b); } } /*輸出結(jié)果 true 0 0 0 0 0.0 0.0 null false */
Java中類屬性的初始化
我們知道一個類(class)要被使用必須經(jīng)過裝載,連接初始化這樣的過程。下面先對這三階段做一個簡單的描述,之后會結(jié)合一個簡單的例子來說明java中類的初始化過程。
在裝載階段,類裝載器(Bootstrap ClassLoader 或者用戶自定義的ClassLoader) 把編譯形成的class文件載入內(nèi)存,創(chuàng)建類相關(guān)的Class對象,這個Class對象封裝了我們要使用的類的類型信息。
連接階段又可以分為三個子步驟:驗(yàn)證、準(zhǔn)備和解析
驗(yàn)證就是要確保java類型數(shù)據(jù)格式 的正確性,并適于JVM使用。
準(zhǔn)備階段,JVM為靜態(tài)變量分配內(nèi)存空間,并設(shè)置默認(rèn)值,注意,這里是設(shè)置默認(rèn)值,比如說int型的變量會被賦予默認(rèn)值0 。在這個階段,JVM可能還會為一些數(shù)據(jù)結(jié)構(gòu)分配內(nèi)存,目的 是提高運(yùn)行程序的性能,比如說方法表。
解析過程就是在類型的常量池中尋找類、接口、字段和方法的符號引用,把這些符號引用替換成直接引用。這個階段可以被推遲到初始化之后,當(dāng)程序運(yùn)行的過程中真正使用某個符號引用的時候 再去解析它。
類會在首次被“主動使用”時執(zhí)行初始化,為類(靜態(tài))變量賦予正確的初始值。在Java代碼中,一個正確的初始值是通過類變量初始化語句或者靜態(tài)初始化塊給出的。
而我們這里所說的主動使用 包括
1. 創(chuàng)建類的實(shí)例
2. 調(diào)用類的靜態(tài)方法
3. 使用類的非常量靜態(tài)字段
4. 調(diào)用Java API中的某些反射方法
5. 初始化某個類的子類
6. 含有main()方法的類啟動時
初始化一個類包括兩個步驟
1、 如果類存在直接父類的話,且直接父類還沒有被初始化,則先初始化其直接父類
2、 如果類存在一個初始化方法,就執(zhí)行此方法
注:初始化接口并不需要初始化它的父接口。
Java中final變量為什么在使用前必須要進(jìn)行初始化
final修飾的變量表示賦值之后不能再進(jìn)行更改,系統(tǒng)賦默認(rèn)值也算賦值,因此系統(tǒng)也不會賦默認(rèn)值。
如果不在定義的時候或者構(gòu)造函數(shù)中對final變量進(jìn)行賦值的話,則生成的對象中final變量的值是未知的(編譯器也會直接報(bào)錯),因此必須進(jìn)行初始化。
如果用static final同時修飾變量的話,則變量必須在定義的時候進(jìn)行初始化。因?yàn)閟tatic變量屬于類,在調(diào)用構(gòu)造函數(shù)之前就已經(jīng)被系統(tǒng)賦予默認(rèn)值了。
如果不在定義的時候初始化,那么既無法在構(gòu)造函數(shù)中初始化,系統(tǒng)也不會賦默認(rèn)值。則該變量被定義出來是毫無意義的
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java 發(fā)送http請求上傳文件功能實(shí)例
本文通過實(shí)例代碼給大家介紹了Java 發(fā)送http請求上傳文件功能,需要的朋友參考下吧2017-06-06解決IDEA啟動springboot項(xiàng)目報(bào)錯java.lang.ClassNotFoundException:?jav
這篇文章主要介紹了解決IDEA啟動springboot項(xiàng)目報(bào)錯java.lang.ClassNotFoundException:?javax.servlet.ServletContext問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01Java Socket編程心跳包創(chuàng)建實(shí)例解析
這篇文章主要介紹了Java Socket編程心跳包創(chuàng)建實(shí)例解析,具有一定借鑒價(jià)值,需要的朋友可以參考下2017-12-12使用jib插件為Java應(yīng)用構(gòu)建鏡像的方法
這篇文章主要介紹了使用jib插件為Java應(yīng)用構(gòu)建鏡像,要是用戶本地沒安裝docker,可以使用jib制作出帶有鏡像的tar文件,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08springboot配置多數(shù)據(jù)源(靜態(tài)和動態(tài)數(shù)據(jù)源)
在開發(fā)過程中,很多時候都會有垮數(shù)據(jù)庫操作數(shù)據(jù)的情況,需要同時配置多套數(shù)據(jù)源,本文主要介紹了springboot配置多數(shù)據(jù)源(靜態(tài)和動態(tài)數(shù)據(jù)源),感興趣的可以了解一下2023-09-09使用Spring AOP監(jiān)控指定方法執(zhí)行時間的代碼詳解
這篇文章主要介紹了使用Spring AOP監(jiān)控指定方法執(zhí)行時間,文中通過代碼示例給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-08-08Spring?Security?基于URL的權(quán)限判斷源碼解析
這篇文章主要介紹了Spring?Security?基于URL的權(quán)限判斷問題,我們想要實(shí)現(xiàn)自己的基于請求Url的授權(quán)只需自定義一個?AccessDecisionManager即可,接下來跟隨小編一起看看實(shí)現(xiàn)代碼吧2021-12-12