淺析Java中 new 和不 new 對象的區別


  今天在寫代碼時碰到一個提示,提示如下:

  提示的信息是說:new OrderVO() 是冗余的。所以准備研究一下是怎么回事。

// 例如以下兩種情況 // 場景1
ArrayList<BookInfo> InfoList=null; BookInfo bookinfo=null; bookinfo=test.getInfo(); // 場景2
ArrayList<BookInfo> InfoList=new ArrayList<BookInfo>(); BookInfo bookinfo=new BookInfo(); bookinfo=test.getInfo();

  首先要明白:Java 里對象傳遞的時候,傳遞的都是引用(也就是對象的地址),這比傳遞整個對象高效的多。而基礎類型,int,double等傳遞的才是值。

  比如:(new ArrayList).add(new String(“hello”)),jvm只是把 new String(“hello”) 的地址存入到了列表 list 里面。

  String str = new String(“Test”),是開辟內存放入了對象,並把它的引用賦給str,即str是一個地址,它指向對象 new String(“test”) 所開辟的內存空間,該空間中有值‘test’。

  同理,BookInfo bookinfo = null 與 BookInfo bookinfo=new BookInfo()

  前者,是聲明了一個對象(的引用),jvm並沒有開辟內存放入一個對象;

  而后者,在聲明了一個對象的引用后,又把新開辟的沒有存儲任何有效值的對象的地址賦給了他。

  bookinfo = test.getinfo(),又把它指向了另一個地址,也就是說原來開辟的內存並沒有用,那就沒有意義。

  但是java虛擬機自動垃圾回收機制會判斷並回收內存的。不用想太多,完全可以寫成:ArrayList InfoList=new ArrayList();BookInfo bookinfo=infoList.getInfo()。

  綜上:如果你的類在創建后,要自己讀寫數據,那就必須初始化;如果像Bookinfo那樣,完全是為了從其他地方接收引用,也完全可以省了new。

  還有我們需要知道的是,在使用對象的時候一般都是通過new,我們知道通過new關鍵字實際上是在 heap(堆中)開辟了一塊內存,而等號右邊的這個對象實際上就是一個內存地址,不信的話,可以打印出來看看。其實並不僅僅這么簡單。堆上分配的是大小不定的對象,而棧上對象的大小是固定的,基本數據類型(int,short)什么的都在棧上,堆上對象的引用也在棧上,如果堆上的對象在棧(stack)上沒有了引用,它就被GC回收了。

  所以我們可以驗證一下:

  當代碼沒有執行到下面的 orderVO 賦值時,下面是沒有 orderVO 變量的;當執行了 orderVO 賦值之后才在下面的變量信息里出現了 orderVO。因此可以印證上面的判斷。先聲明,並沒有開辟內存,到執行了查詢賦值之后才開辟了內存空間。

  然后我們可以繼續嘗試一下:

  初始化之后,直接get,就不會報冗余的那個提示了。但是不初始化,直接get,就報錯了。

  結論:如果類在創建后,要自己讀寫數據,那就必須初始化;如果是為了從其他地方接收引用,可以省略new。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM