今天在寫代碼時碰到一個提示,提示如下:
提示的信息是說: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。