Java筆記1

1、Java的值傳遞html

(做者:知乎用戶
連接:https://www.zhihu.com/question/20628016/answer/15683373
來源:知乎
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處)

java

Java 中的全部函數調用都是值傳遞。算法

值傳遞是指,函數在調用時,傳遞的參數不是實參自己,而是它的副本。spring

引用傳遞是指,函數在調用時,傳遞的參數就是實參自己(的地址)。編程

顯然,在使用引用傳遞的狀況下,在函數體內能夠對參數自己進行修改,修改結果會對函數調用者產生影響。而使用值傳遞,因爲函數內對參數的修改實際上不是對參數自己,而是對參數的副本進行的修改,所以,修改結果不會對調用者產生影響。數組

在 Java 中,對象(類的實例)都是經過引用來訪問的。例如:安全

Object foo = new Object();

其中,foo 是一個引用,指向了新建立的這個 Object 對象。併發

的確,你能夠在某個方法(函數)中,對其參數引用的對象進行修改,例如:編程語言

void doSth(Object bar) { bar.attr = newValue; } 


假設某個調用者調用了 doSth 方法,而且將 foo 傳入。在方法返回以後,foo 所引用的對象的 attr 屬性變成了 newValue。但這並非值傳遞。由於 doSth 方法體內修改的是 foo 所引用的對象,而不是 foo 自己。函數

在 Java 中,你毫不可能在方法體內,把做爲參數傳入的引用自己指向其餘對象。由於 Java 全部的函數調用都是值傳遞。這樣的修改只會修改參數的副本,而不是參數自己。

--------------

Java 的設計目的之一就是爲了填 C/C++ 的各類「坑」,讓編程語言更加易用和易於理解,例如垃圾自動回收機制,單繼承策略,等等。引用傳遞使得方法內部能夠對方法外的數據進行修改,這無疑增長了必定的(但我以爲這不多)危險性。固然,這會使語言的靈活性下降,就算你對你的數據掌控得很好,你也不能爲所欲爲地修改它。事實上,你徹底能夠經過傳遞引用參數來修改方法外建立的對象。所以,受到制約的實際上就只有那些原生類型而已。

或許這是 Java 注重安全性與實用性而寧願放棄一些靈活性的設計哲學的一種體現。
 

1.這個解釋的不錯,其實不用長篇大論,本質上講java沒有所謂的引用(地址)傳遞是由於java規定了引用自己不能操做修改內存地址;
2.值傳遞與引用傳遞的最大區別就是內存屬於copy仍是share,前者屬於copy,基本類型直接copy內容,object的變量copy的是內存地址(也就是引用),copy過來的引用是被包裝過的,所以在java裏沒辦法操做引用去修改變量的內存地址,也就是你代碼解釋的狀況;
3.假如說java中有"引用傳遞",那麼違背了java資深的規定,引用是"只讀"的(而C++的指針是可讀寫的);
4.而C++因爲採用的是指針,指針是"可寫"的,所以才分別給了「」copy(值傳遞)「」和"share(地址傳遞)"來做明確區分.

 

2、JAVA中堆和棧的區別

 

在函數中定義的一些基本類型的變量和對象的引用變量都在函數的棧內存中分配。   

 

  當在一段代碼塊定義一個變量時,Java就在棧中爲這個變量分配內存空間,當超過變量的做用域後,Java會自動釋放掉爲該變量所分配的內存空間,該內存空間能夠當即被另做他用。   

 

  堆內存用來存放由new建立的對象和數組。   

 

  在堆中分配的內存,由Java虛擬機的自動垃圾回收器來管理。   

 

  在堆中產生了一個數組或對象後,還能夠在棧中定義一個特殊的變量,讓棧中這個變量的取值等於數組或對象在堆內存中的首地址,棧中的這個變量就成了數組或對象的引用變量。   

 

  引用變量就至關因而爲數組或對象起的一個名稱,之後就能夠在程序中使用棧中的引用變量來訪問堆中的數組或對象。   

 

java中變量在內存中的分配

 

一、類變量(static修飾的變量):在程序加載時系統就爲它在堆中開闢了內存,堆中的內存地址存放於棧以便於高速訪問。靜態變量的生命週期--一直持續到整個"系統"關閉

 

二、實例變量:當你使用java關鍵字new的時候,系統在堆中開闢並不必定是連續的空間分配給變量(好比說類實例),而後根據零散的堆內存地址,經過哈希算法換算爲一長串數字以表徵這個變量在堆中的"物理位置"。 實例變量的生命週期--當實例變量的引用丟失後,將被GC(垃圾回收器)列入可回收「名單」中,但並非立刻就釋放堆中內存

 

三、局部變量:局部變量,由聲明在某方法,或某代碼段裏(好比for循環),執行到它的時候在棧中開闢內存,當局部變量一但脫離做用域,內存當即釋放

 

附:java的內存機制

 

Java 把內存劃分紅兩種:一種是棧內存,另外一種是堆內存。

      在函數中定義的一些基本類型的變量和對象的引用變量都是在函數的棧內存中分配,當在一段代碼塊定義一個變量時,Java 就在棧中爲這個變量分配內存空間,當超過變量的做用域後,Java 會自動釋放掉爲該變量分配的內存空間,該內存空間能夠當即被另做它用。

  堆內存用來存放由 new 建立的對象和數組,在堆中分配的內存,由 Java 虛擬機的自動垃圾回收器來管理。在堆中產生了一個數組或者對象以後,還能夠在棧中定義一個特殊的變量,讓棧中的這個變量的取值等於數組或對象在堆內存中的首地址,棧中的這個變量就成了數組或對象的引用變量,之後就能夠在程序中使用棧中的引用變量來訪問堆中的數組或者對象,引用變量就至關因而爲數組或者對象起的一個名稱。引用變量是普通的變量,定義時在棧中分配,引用變量在程序運行到其做用域以外後被釋放。而數組和對象自己在堆中分配,即便程序運行到使用 new 產生數組或者對象的語句所在的代碼塊以外,數組和對象自己佔據的內存不會被釋放,數組和對象在沒有引用變量指向它的時候,才變爲垃圾,不能在被使用,但仍然佔據內存空間不放,在隨後的一個不肯定的時間被垃圾回收器收走(釋放掉)。

  這也是 Java 比較佔內存的緣由,實際上,棧中的變量指向堆內存中的變量,這就是 Java 中的指針!

 

C或C++中的指針詳解

 

3、Java的ThreadLocal源碼分析

 

4、Java  ThreadLocalMap的引伸 (強引用,弱引用,軟引用,虛引用)

 

5、Redis服務及應用場景

 

6、Java Spring Redis(spring配置,RedisTemplate類詳解,@CachePut\@Cacheable\@CacheEvict)

 

7、Java併發編程:線程池的使用       ThreadPoolExcuter詳解

 

8、併發隊列ConcurrentLinkedQueue和阻塞隊列LinkedBlockingQueue用法

 

9、FIFO原則,JAVA CAS原理深度分析(java.util.concurrent包源碼實現、Lock 與 Synchronized 的比較)

http://blog.csdn.net/hsuxu/article/details/9467651(CAS原理)

https://www.cnblogs.com/onlywujun/articles/3531568.html(Lock源碼分析)

相關文章
相關標籤/搜索