1. 程式人生 > >Java記憶體、成員變數、區域性變數

Java記憶體、成員變數、區域性變數

一 java記憶體分配 

Java 中的資料型別分為 
1. 基本型別(原始資料型別) byte short int long float double char boolean 
基本型別的變數持有原始值。 
2. 複合資料型別(引用型別),引用型別持有引用值(即對某個物件的引用,而非物件本身)。

一般Java在記憶體分配時會涉及到以下區域: 
1. 暫存器:我們在程式中無法控制 
2. 棧:存放基本型別的資料和物件的引用但物件本身不存放在棧中,而是存放在堆中 
3. 堆:存放用new產生的資料 
4. 靜態域:存放在物件中用static定義的靜態成員 
5. 常量池:存放常量 
6. 非RAM儲存:硬碟等永久儲存空間 
其中主要是堆,棧的儲存。

堆,棧

  1. 函式中定義的一些基本型別的資料變數物件的引用變數都在函式的棧記憶體中分配。 
    棧的優勢是存取速度比堆要快,僅次於直接位於CPU 的暫存器,而且資料可以共享。 
    存在棧中的資料大小與生存週期必須是確定的。因此裡面的變數通常是區域性變數、函式引數等。 
    當在一段程式碼塊定義一個變數時(區域性變數),Java就在棧中 為這個變數分配記憶體空間,當該變數退出該作用域後,Java會自動釋放掉為該變數所分配的記憶體空間,該記憶體空間可以立即被另作他用。

  2. 堆記憶體用來存放由new建立的物件和陣列。 在堆中分配的記憶體,由Java虛擬機器的自動垃圾回收器來管理。

在堆中產生了一個數組或物件後,還可以 在棧中定義一個特殊的變數,讓棧中這個變數的取值等於陣列或物件在堆記憶體中的首地址,棧中的這個變數就成了陣列或物件的引用變數。

 
引用變數是普通的變數,定義時在棧中分配,引用變數在程式執行到其作用域之外後被釋放。而陣列和物件本身在堆中分配,即使程式 執行到使用 new 產生陣列或者物件的語句所在的程式碼塊之外,陣列和物件本身佔據的記憶體不會被釋放,陣列和物件在沒有引用變數指向它的時候,才變為垃圾,不能在被使用,但仍 然佔據記憶體空間不放,在隨後的一個不確定的時間被垃圾回收器收走(釋放掉)。

棧,就是那些由編譯器在需要的時候分配,在不需要的時候自動清除的變數的儲存區。裡面的變數通常是區域性變數、函式引數等。

堆,就是那些由new分配的記憶體塊,他們的釋放編譯器不去管,由我們的應用程式去控制,一般一個new就要對應一個delete。如果程式設計師沒有釋放掉,那麼在程式結束後,

作業系統會自動回收。

二 成員變數,區域性變數

class A 
{ 
int a;//成員變數 
public static void main(String[] args) 
{ 
//類變數
static int c;
int b;//區域性變數 
} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

成員變數:作為類的成員而存在,直接存在於類中。

類變數:static 修飾,靜態變數儲存在方法區。

區域性變數:方法內部,塊內部都是區域性,執行指令退出那個區域性,區域性變數自動清除。

1.成員變數可以被public,protect,private,static等修飾符修飾,而區域性變數不能被控制修飾符及static修飾;兩者都可以定義成final型

2.成員變數儲存在堆,區域性變數儲存在棧

3.存在時間不同

4.成員變數有預設值,(被final修飾且沒有static的必須顯式賦值),區域性變數不會自動賦值,區域性變數在使用前必須被程式設計師主動的初始化,然後才能使用。

看下面對比成員變數區域性變數:

public class Variable { 
int i; 
void test() { 
   int j=8; 
   if(j==i) 
    System.out.println("相等"); 
   else 
    System.out.println("不相等"); 
} 
public static void main(String[] args) { 
   Variable v=new Variable(); 
   v.test(); 
} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

程式二:

public class Variable { 
   void test() { 
   int i; 
   int j=8;
   //這裡 i 被使用了,但是還沒有賦值,所以報錯 
   if(j==i) 
    System.out.println("相等"); 
   else 
    System.out.println("不相等"); 
} 
public static void main(String[] args) 
{ 
   Variable v=new Variable(); 
   v.test(); 
} 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

第一個程式很正常,編譯時不會出錯。第二個程式編譯時會錯誤,因為區域性變數沒有初始化。成員變數有預設值,(被final修飾且沒有static的必須顯式賦值),區域性變數不會自動賦值

public static int transeInt(String s){

        //digit不會報錯,result 會報錯
        int digit;
        int result;

        if(s.length()==0||s==null)
            System.out.println("錯誤字串");

        for(int i=0;i<s.length();i++){
            //這裡digit被顯示的賦值了(所以不一定是建立之後就被賦值)
            digit = s.charAt(i)-'0';
            //result*10   還未被賦值就被使用了,所以報錯
            result = result*10+digit;
        }

        return result;
    }

相關推薦

Java 006 面向物件(類物件成員變數區域性變數匿名物件封裝)

知識點梳理 心得體會 小知識點 1.Java面向物件的特徵:封裝、抽象、繼承、多型 2.this關鍵字,對當前類的物件的引用,誰呼叫這個方法,方法中的this就代表誰,一般有this就是成員變數,沒有this就是區域性變數 3.成員方法定義與定義一般方法一樣,但需要去掉st

Java學習筆記02--成員變數區域性變數建構函式構造程式碼塊this關鍵字static關鍵字靜態函式

成員變數和區域性變數 自定義的位置區別: 成員變數是定義在方法之外,類之內的變數。 區域性變數是宣告在方法之內的變數。 作用上的區別: 成員變數的作用描述一類事物的屬性。 區域性變數的作用是提供一個變數給方法內部使用的。 生命週期的區別;

第十二Java成員變數區域性變數的區別

成員變數與區域性變數的區別: 0、定義的位置上區別: 成員變數:  定義在方法之外,類之內的變數 區域性變數:  定義在方法之內的變數 1、應用範圍的區別          成員變數在整個類內都有效             區域性變數只在其宣告的方法內有效 2、生命

1.成員變數&全域性變數&區域性變數&靜態變數常量和方法

原文:https://blog.csdn.net/panpuqin/article/details/75091468  原文:https://blog.csdn.net/bobo_993/article/details/73655765  @interface 

關於java成員變數區域性變數以及成員方法的記憶體區別問題

今天去面試遇到了有關成員變數與區域性變數以及成員方法的問題,主要是涉及所處記憶體的問題和初始化問題,簡單的總結一下: 1.java中成員變數處在堆記憶體(成員方法不呼叫時存在方法區中的靜態區)中,區域性變數處在棧記憶體中; 知其然知其所以然,我們簡單瞭解一下Java記憶體分配:

java第六天---面向物件成員變數成員方法封裝

1 面向物件的特徵 封裝、繼承、多型   2 類與物件         類:是一組相關的屬性和行為的集合      物件:是該類事物的具體體現        

Java三大變數分別是類變數例項變數區域性變數

一、什麼是變數:就是內容可以改變的量,它與常量相對應。而這三大變數實際上是從變數的作用域來定義和劃分的。 1、類變數,是歸屬類的變數,它是通過在定義類的屬性的時,增加static修飾符,所以又稱為靜態變數。類變數不僅可以直接通過類名+點操作符+變數名來操作,也

Java例項變數變數區域性變數

一、例項變數 也叫物件變數、類成員變數;從屬於類由類生成物件時,才分配儲存空間,各物件間的例項變數互不干擾,能通過物件的引用來訪問例項變數。但在Java多執行緒中,例項變數是多個執行緒共享資源,要注意同步訪問時可能出現的問題。 <span style="font-si

java成員變數區域性變數的初始化和記憶體中的執行機制

成員變數:   當系統載入類或建立類的例項時,系統會自動為成員變數分配記憶體空間,並在分配記憶體空間後,自動為成員變數指定初始值。 eyeNum是類屬性。name是例項屬性 所有person例項訪問eyeNum都將訪問person類的eyeNum屬性。訪問的是同一塊記憶

Java學習:“this”的引用及類變數例項變數區域性變數

class caculate { static int staticVar = 0; //類變數、靜態變數 static final float STATIC_CONSTANT = 1; /

Java記憶體成員變數區域性變數

一 java記憶體分配 這裡只是在網上找的一些資料; Java 中的資料型別分為 1. 基本型別(原始資料型別) byte short int long float double char boolean 基本型別的變數持

java成員變數區域性變數

1.成員變數   在類中定義,用來描述物件將要有什麼。 2.區域性變數 在類的方法中定義,在方法中臨時儲存資料 成員變數和區域性變數區別 1.作用域不同 成員變數的作用域在整個類內部都是可見的 區域性變數的作用僅限於定義它的方法、 2.初始值不同 jav

第三章(3) lambda表示式型別檢查型別推斷以及區域性變數

     1.型別檢查      當我們在之前第一次提到lambda表示式的時候,說它可以為函式式介面生成一個例項。然而,Lambda表示式本身並不包含它在實現哪個函式式介面的資訊。為了全面瞭解Lambda表示式,你

JAVA基礎(11)---成員變數區域性變數

變數的分類: 按照變數宣告的位置(作用的範圍):     成員變數: 宣告在類的內部,方法的外部的變數,稱為成員變數                區域性變數:宣告在方

C# 定義了 7 種變數類別:靜態變數例項變數陣列元素值引數引用引數輸出引數和區域性變數

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Python之路Python全域性變數區域性變數函式多層巢狀函式遞迴 Python之路Python全域性變數區域性變數函式多層巢狀函式遞迴

Python之路Python全域性變數與區域性變數、函式多層巢狀、函式遞迴 一、區域性變數與全域性變數   1、在子程式中定義的變數稱為區域性變數,在程式的一開始定義的變數稱為全域性變數。全域性變數作用域是整個程式,區域性變數作用域是定義該變數的子程式。 全域性變數

Java中ThreadLocal,成員變數區域性變數

一.成員變數和區域性變數 1.程式例子: public class HelloThreadTest { public static void main(String[] args) { HelloThread r = new HelloThread();

java基礎筆記(七)成員變數區域性變數

先來看成員變數和區域性變數是什麼: 成員變數: 定義在類裡的變數 public class Person { private String name; int age;} 區域性變數 在方法定義中,或宣告方法上的變數 public class Person { priva

java類基礎1-成員變數區域性變數

成員變數:寫在類體的裡面,方法體的外面,宣告時可以不進行初始化值,可以被本類或其他類的方法進行呼叫。區域性變數:寫在方法體的裡面,宣告時必須進行初始化,只能在宣告區域性變數的方法內進行呼叫。 public class Student { String name; int age=20; b

JS中最經典的全域性變數區域性變數問題(1作用域和作用域鏈 2變數宣告提前)

var a = 10; function test(){ a = 100; console.log(a); console.log(this.a); var a; console.log(a); } test(); 1、程式的執行結果為:100