日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java heap space 解决方法_Java静态方法/变量,非静态方法/变量的区别,今天一并帮你解决

發布時間:2025/3/20 java 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java heap space 解决方法_Java静态方法/变量,非静态方法/变量的区别,今天一并帮你解决 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

靜態/非靜態 方法/變量的寫法

大家應該都明白靜態方法/字段比普通方法/字段的寫法要多一個static關鍵字,簡單寫下他們的寫法吧,了解的可以直接略過

class Test{ // 靜態變量 public static int id = 1; // 普通變量 public int usualId = 2; // 靜態常量 public static final int finalNextId = 3; // 靜態方法 public static void A(){ // 靜態方法只能訪問靜態字段,不能訪問非靜態字段 System.out.println("this is static function A!"); } // 普通方法 public void B(){ // 普通方法可以訪問靜態字段和非靜態字段 System.out.println("this is usual function B!"); }}

靜態變量

靜態變量(帶有static關鍵字的字段)是屬于類的,所有該類的對象共用該字段;非靜態變量(普通字段)是屬于類的對象的,每一個該類的對象都有自己的非靜態字段,他們互不影響。

class Test{ // 靜態變量 public static int id = 1; // 普通變量 public int usualId = 2;}class TestA{ // 對于靜態字段,不實例化類(即創建對象)就可使用 Test.id; // 對于普通字段,Test.usualId 就會報錯 // 對于普通字段,需要先實例化類 Test test = new Test(); test.usualId; // 不會報錯}

靜態方法

靜態方法與普通方法的區別,與靜態字段與普通字段的區別類似靜態方法是不在對象上執行的方法,在調用靜態方法時,不需要實例化該類而調用普通方法必須實例化該類。

class Test{ // 靜態方法 public static void A(){ // 靜態方法只能訪問靜態字段,不能訪問非靜態字段 System.out.println("this is static function A!"); } // 普通方法 public void B(){ // 普通方法可以訪問靜態字段和非靜態字段 System.out.println("this is usual function B!"); }}class TestA{ // 對于靜態方法,不實例化類(即創建對象)就可調用 Test.A(); // 對于普通字段,Test.B()就會報錯 // 對于普通方法,需要先實例化類 Test test = new Test(); test.B(); // 不會報錯}

可以了解下Java中類的生命周期,就能知道為什么訪問靜態方法/字段不需要實例化類而訪問非靜態的方法/字段需要實例化類靜態字段/方法在類的連接階段就存在了,幾乎可以理解為類存在,靜態字段/方法就存在;非靜態字段/方法在類初始化后(new 類名)才會存在,也就是對象存在后,非靜態字段/方法才會存在。

類的生命周期

此部分幾乎搬運了“三級小野怪”的文章,參考鏈接:https://blog.csdn.net/zhengzhb/article/details/7517213

當我們編寫一個Java源文件后,經過編譯會生成一個后綴名為class的文件,這種文件叫做字節碼文件,只有這種字節碼文件才能夠在Java虛擬機中運行,Java類的聲明周期就是指一個class文件從加載到卸載的全過程。

一個Java類的完整的生命周期會經歷加載,連接,初始化,使用,卸載五個階段,當然也有在加載或者連接之后沒有被初始化就直接被使用的情況。

jvm中的幾個重要的內存區域

方法區:專門用來存放已經加載的類信息,常量,靜態變量以及方法代碼的內存區域常量池:是方法區的一部分,主要用來存放常量和類中的符號引用等信息;堆區:存放類的對象實例棧區:也叫Java虛擬機棧,由一個個的棧幀組成的后進先出的棧式結構,存放方法運行時產生的局部變量,方法出口等信息。當調用一個方法時,虛擬機棧就會創建一個棧幀存放這些數據,當方法調用完成時,棧幀消失,如果方法調用了其他方法,則繼續在棧頂創建新的棧幀。

加載

在加載階段,Java虛擬機會找到需要加載的類,并把類信息放到jvm的方法區中,然后堆中實例化。是類的生命周期中的第一個階段,加載階段之后是連接階段,但是有時連接階段并不會等加載階段完成之后才開始,而是交叉進行,可能一個類只加載了一部分之后,連接階段就已經開始了。但是兩個階段總的開始時間和完成時間總是固定的:加載階段總在連接階段之前開始,連接階段總是在加載階段完成之后完成。

連接

連接階段主要任務是做一些加載后的驗證工作以及一些初始化前的準備工作

驗證:當一個類被加載會后,驗證類是否合法,比如這個類的變量與方法是不是有重復,數據類型是否有效等,目的是保證加載的類能夠被jvm所運行。準備:為類的靜態變量分配內存并設為jvm默認的初始值,非靜態變量則不分配內存。需要注意的是,這時候靜態變量的初值是jvm默認的初始值而不是我們在程序中設定的初值。jvm默認的初值是這樣的:1.基本類型(int、long、short、char、byte、boolean、float、double)的默認值為0。2.引用類型的默認值為null。3.常量的默認值為我們程序中設定的值,比如我們在程序中定義final static int a = 100,則準備階段中a的初值就是100。解析

初始化

如果一個類被直接引用就會觸發類的初始化,直接引用的情況有:

通過new關鍵字實例化對象,讀取或設置類的靜態變量,調用類的靜態方法通過反射執行以上三種行為初始化子類的時候,會觸發父類的初始化作為程序入口直接運行時(也就是直接調用main方法)除了以上四種情況,其他使用類的方法叫做被動引用,被動引用不會觸發類的初始化主動引用代碼示例

class InitClass{ static { System.out.println("初始化InitClass") } public static String a = null; public static void method(){}}class SubInitClass extends InitClass{}public class Test1{ public static void main(){ // 主動引用引起類的初始化:new 對象、讀取或者是類的靜態變量,調用類的靜態方法 new InitClass(); InitClass.a = ""; String a = InitClass.a; InitClass.method(); // 主動引用引起類的初始化,通過反射實例化對象,讀取或設置類的靜態變量,調用類的靜態方法 Class cls = InitClass.class; cls.newInstance(); Field f = cls.getDeclaredField("a"); f.get(null); f.set(null,"s"); Method md = cls.getDeclaredMethod("method"); md.invoke(null, null); // 主動引用引起類的初始化,實例化子類 new SubInitClass(); }}

初始化過程:按照順序自上而下運行類中的變量賦值語句和靜態語句,如果有父類,則首先按照順序運行父類中的變量賦值語句和靜態語句。在初始化階段,只會初始化與類相關的靜態賦值語句和靜態語句,也就是有static關鍵字修飾的信息,而沒有static修飾的賦值語句和執行語句在實例化對象時才會運行

使用類的使用包括主動引用和被動引用,主動引用上面說過了,下面主要說下被動引用

引用父類的靜態字段,只會引起父類的初始化,而不會引起子類的初始化;定義類數組,不會引起類的初始化;引用類的常量,不會引起類的初始化。被動引用代碼示例

class InitClass{ static{ System.out.println("初始化InitClass"); } public static String a = null; public final static String b = "b"; public static void method(){}}class SubInitClass extends InitClass{ static { System.out.println("初始化SubInitClass"); }}public class Test4 { public static void main(String[] args) throws Exception{ // String a = SubInitClass.a;// 引用父類的靜態字段,只會引起父類初始化,而不會引起子類的初始化 // String b = InitClass.b;// 使用類的常量不會引起類的初始化 SubInitClass[] sc = new SubInitClass[10];// 定義類數組不會引起類的初始化 }}

卸載

如果滿足下面的情況,類就會被卸載:

該類所有的實例都已經被回收,也就是java堆中不存在該類的任何實例。加載該類的ClassLoader已經被回收。該類對應的java.lang.Class對象沒有任何地方被引用,無法在任何地方通過反射訪問該類的方法。

原文鏈接:https://blog.51cto.com/14801695/2493438

總結

以上是生活随笔為你收集整理的java heap space 解决方法_Java静态方法/变量,非静态方法/变量的区别,今天一并帮你解决的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。