『壹』 java沒有指針更安全,誰能舉個簡單的例子啊。 1,c有指針,java用引用實現了2,java沒指針,c用指針出錯了
java事實上是封裝了指針(即用引用實現了指針),不知道你對java了解程度如何,所以就打個比方來說明兩者的關系和區別。家裡有遙控器吧,假設你家電視能夠收到1-40個頻道,你想看25頻道的話,直接按數字鍵2、5就能轉入到該頻道,但是有一個問題,如果你輸入了4、1怎麼辦,電視上分明沒有41頻道!(這就出現了指針不安全的問題!)為了避免這個問題,又能實現換台功能,現在遙控器只允許你使用上下鍵換台,這樣就避免你直接操作指針了。這就相當於java中的引用
『貳』 Java引用和C++引用的區別
c++ 與java引用具體比較:
c++中一個引用指向的地址不會改變,改變的是指向地址的內容,然而java中引用指向的地址在變!!
如果非要對比著看,那麼Java中的「引用」倒是和C/C++的指針更像一些,和C++的「引用」很不一樣。
java去除指針概念,就用引用羅...
你看 java:
A a = new A(1);
A b = new A(2);
b = a;
沒有問題,a 和 b引用同一個對象A(2),原來的A(1)成為沒有被引用的對象。 垃圾回收機制會在之後的某個時刻把A(1)幹掉。
而C++則不然。C++的引用就語義上說是「別名」【本質是個const指針,又叫指針常量】,而並不是指針的另一種用法:
A a = A(1);
A b = A(2);
A& c = b; //c 是 b的別名
c = a; //並不是 c 引用 a,而是拷貝操作 c.operator= ( a )
就語言機制來說,java的引用是用來管理和命名對象;
而,C++的引用機制是很純粹的,就是別名而已。
每種語言的特性都是整體的有機部分。
我們知道, java的引用機制是一個很復雜的機制。他必須區分「基本對象」和「復合對象」,你可以想像一下,如果其中沒有基本對象,那麼我們如何完成對象的復制? 唯一的解決方案是提供兩個等於號,或者一律用構造函數.... 但是綜合來看,他和垃圾回收形成了相當完美的組合方案。
而C++ 的引用機制為運算符重載提供了大幅度的支持。C++ 的引用是用類「模擬」基本對象的根本要求。 如果C++使用java那種引用,那麼原本漂亮的 operator[]、 proxy class 等就很難實現了。 更進一步, C++ 的運算符重載對 C++ 的模版機制提供了強力的支持
在c++中,引用只是對於一個變數起的別名,一旦定義就無法修改,即無法再指向其他變數,如程序中,對於a的引用的任何操作都等同於對於a的操作。
java定義的引用並不是這樣。在java中,引用相當與指針,它與c中的指針主要有兩個區別:一是引用不能進行地址操作,如數組的加一 操作,相當於引用只是只是指向數據的一個副本,而不是數據本身,這樣就避免了由於對於地址的誤操作而改變其他變數的值,甚至危害到系統的安全。二是 java中的引用只能指向對象,他的引用是在實例化對象時系統直接生成的,因此對於普通數據類型是不能進行引用定義的,如果要對普通數據類型進行函數調用 時的地址傳遞(即java中的引用傳遞),必須把數據封裝到類中。
java的這種特性使得在java的函數或類的參數傳遞時可以實現與c中指針相同的功能。
具體應用:
指針和引用在C++中很常用,但是對於它們之間的區別很多初學者都不是太熟悉,下面來談談他們2者之間的區別和用法。
1.指針和引用的定義和性質區別:
(1)指針:指針是一個變數,只不過這個變數存儲的是一個地址,指向內存的一個存儲單元;而引用跟原來的變數實質上是同一個東西,只不過是原變數的一個別名而已。如:
int a=1;int *p=&a;
int a=1;int &b=a;
上面定義了一個整形變數和一個指針變數p,該指針變數指向a的存儲單元,即p的值是a存儲單元的地址。
而下面2句定義了一個整形變數a和這個整形a的引用b,事實上a和b是同一個東西,在內存佔有同一個存儲單元。
(2)可以有const指針,但是沒有const引用;
(3)指針可以有多級,但是引用只能是一級(int **p;合法 而 int &&a是不合法的)
(4)指針的值可以為空,但是引用的值不能為NULL,並且引用在定義的時候必須初始化;
(5)指針的值在初始化後可以改變,即指向其它的存儲單元,而引用在進行初始化後就不會再改變了。
(6)"sizeof引用"得到的是所指向的變數(對象)的大小,而"sizeof指針"得到的是指針本身的大小;
(7)指針和引用的自增(++)運算意義不一樣;
2.指針和引用作為函數參數進行傳遞時的區別。
(1)指針作為參數進行傳遞:
『叄』 java的引用就是C或者C++里說的指針嗎
個人感覺java引用使用上和c++的指針差不多。java引用可以為null,指針也可以。java引用和c++的指針一般都要new一個對象才能用。
不過語法上又像c++的引用,可以直接用成員訪問符,僅此而已。
其實c++的指針和引用本身區別也沒有多少,引用這個概念就是從c語言,指針擴展來的。
『肆』 關於java中的引用型變數和c中的指針的差別問題。比如我在c中寫一句 int a=1; 那就在
應該說最大差別在GC.java的垃圾處理機制.
c的話你需要自己釋放不在使用的內存,java不需要.
當前緩存中數據過多也會 內存溢出.
你的理解是對的.
int a=1;首先它會在棧中創建一個變數為a的引用,然後查找棧中是否有1這個值,如果沒找到,就將1存放進來,然後將a指向1.
然後p = a了.就會先去棧中創建p,然後找a然後找a對應的1.始終找的都是那個1的內存.
你可以判斷下.a==p.判斷的是內存地址.
比較的始終是他們共同指向的那個1的內存地址.
所以a跟c里的指針不一樣,是單獨的兩個對象,只不過他們最終指向的內存地址一樣.
『伍』 JAVA中值調用和引用調用的區別
值傳遞的值是存放在棧裡面的,可以直接訪問傳遞
應用傳遞的值是存放在推裡面的,他要通過棧裡面的一個「路標」(即存放在推裡面的值的一個地址)去訪問,故有」指針「一說,但在JAVA中不能說是指針,不專業
『陸』 Java引用和C++指針的區別
1.類型:引用其值為地址的數據元素,java封裝了的地址,可以轉成字元串查看,長度可以不必關心。C++指針是一個裝地址的變數,長度一般是計算機字長,可以認為是個int。
2.所佔內存: 引用聲明時沒有實體,不佔空間。C++指針如果聲明後會用到才會賦值,如果用不到不會分配內存。
3.類型轉換:引用的類型轉換,也可能不成功,拋異,或者IDE就不能通過。C++指針只是個內存地址,指向那裡,對程序來說還都是一個地址,但可能所指的地址不是程序想要的!
4.初始值:引用初始值為java關鍵字null。C++指針是INT,如不初始化指針,那他的值就不是固定的了。
5.計算:引用是不可以計算的。C++指針是INT,所以他可以計算,所以經常用指針來代替數組下標。
6.控制:引用不可以計算,所以他只能在自己程序里,可以被控制。C++指針是內存地址,也可以計算,所以他有可能指向了一個不歸自己程序使用的內存地址,對於其他程序來說是很危險的,對自己程序來說也是不容易被控制的。
7.內存泄露:JAVA引用不會產生內存泄露。C++指針是容易產生內存泄露的,所以程序員要小心使用,及時回收。
8.作為參數:JAVA的方法參數只是傳值,引用做為參數使用時候,回給函數內引用的值的COPY,所以在函數內交換兩個引用參數是沒意義的,因為
函數只交換的參數的COPY值,但在函數內改變一個引用參數的屬性是有意義的,因為引用參數的COPY所引用的對象是和引用參數是同一個對象。
C++指針做為參數給函數使用,實際上就是他所指的地址在被函數操作,所以函數內用指針參數的操作都將直接作用到指針所指向的地址(變數,對象,函數,等
等)。
9.操作符和聲明:java里用"."。C++指針用"->" 用"*"聲明指針。(似乎這條沒什麼用!)
10.本質:java中的引用和C++中的指針本質上都是想通過一個叫做引用或者指針的東西,找到要操作的目標(變數 對象等),方便在程序里操作。所不同的是JAVA的辦法更安全,方便些,但沒有了C++的靈活,高效。
java中的引用和C++中的指針,他們最好不要混在一起,也不要認為是一回事,只不過他們的作用有些相似,總叫人不自覺的對比。但在我們寫
JAVA程序的時候最好忘記C++的指針,寫C++程序的時候,也不要老惦記著JAVA的引用。只要記得
引用無大小,安全,不可計算,強轉時要小心就好了。
參考
http://blog.csdn.net/b271737818/article/details/3931913
『柒』 java中的引用數據類型是什麼意思
引用數據類型為java兩大數據類型之一
引用數據型在被床架時,首先要在棧上給其引用(句柄)分配一塊內存,而對象的具體信息都存儲在堆內存上,然後由棧上面的引用指向堆中對象的地址。
引用數據類型包括:類、介面類型、數組類型、枚舉類型、註解類型,字元串型;
java另一大數據類型為基本數據類型,其包括包括數值型,字元型和布爾型。
基本數據類型在被創建時,在棧上給其劃分一塊內存,將數值直接存儲在棧上;
『捌』 在JAVA中原始數據類型,與引用數據類型有什麼區別
原始數據類型包括byte、int、char、long、float、double、boolean和short,對應的封裝類booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
。引用類型和原始類型的行為完全不同,並且它們具有不同的語義。原始數據類型保存在棧中,保存的是實際值;引用類型也保存在棧中,保存的是一個實際對象的地址。它們佔用空間大小和存取速度不同;當引用類型和原始類型用作某個類的實例數據時所指定的預設值。對象引用實例變數的預設值為
null,而原始類型實例變數的預設值與它們的類型有關
『玖』 Java中this的用法跟C++的this指針一樣嗎
Java的this是改對象的引用,通過「.」號調用對象。C++的this是指向該對象的指針,用「->」調用對象。Java 的this引用和C++this指針雖然在用法上很相似,但是有本質的區別,引用相當於與對象的索引號,它的值對於程序員沒有任何意義,而指針的值是對象的地址對程序員很有用處。
『拾』 java中指針怎麼理解
實際上,java力圖使程序員忘記指針,這包括2個方面:
第一,java限制指針,去除了指針運算。
第二,java從語法上努力隱藏指針,讓指向某對象的指針看起來更像那個對象本身!
是的,所有的java書籍都讓人忘記了指針這回事,我們彷彿只跟對象打交道。偶爾,會被迫分清引用和
對象的關系。這就是目前的情形。多麼好的想法!對象可比那些個不知所以的指針親和多了!這是一種偉大的抽象!
這里,我們也更願意把引用和對象混淆。是的,為什麼不呢?那樣,整個世界都是對象,太好理解了!
可事實上,為了節省內存,java不能把引用(指針)完全廢除。要知道,復制一個引用(指針)要比
復制整個對象有效得多!所以我們不得不面對引用和對象共存的事實。
下面我就好好分析分析:
指針已經被抽象成了引用,現在指針不能夠隨心所欲的運算,並且看起來就像個對象,完全沒有了指針
的模樣。但它畢竟和對象還是不同的,還要經過一層「轉換」(從指向的那個對象里取數據)。如果我們
在引用滿天飛的時候總想著這樣一層轉換,真的是很不舒服。比如:
String key="name";
String value="hyq";
HashMap map=new HashMap();
map.put(key,value);
你得想著:key只是個引用,value也是個引用,map還是個引用,我們剛剛做的是把key和value
這2個引用放進了map(也是個HashMap對象的引用)中,到時候我就可以通過map這個引用取得
裡面的對應於key引用的value引用!
你不暈我就服了。
一旦你這樣想,你每時每刻都要面對這樣的繞口令。因為我們對對象的操作全部要通過引用!java沒有提供語法讓你直接得到對象!(指的是直接定址)這一點通過比較原始類型很好理解,int i=8,那麼
i就是8,不是什麼指針,要先找到放著8那塊內存的地址再把8拿出來。這樣多直接,多方便啊!
所以,我們對引用最好也這么來理解,就輕松多了。
還是上面的例子,key就是個String,value也是個String,map是個HashMap,我們把key和value
放進map里,將來可以按key取出value。——多簡單!
其實,這樣的理解是很符合人的思維習慣的,我相信大多數人剛學java時都會自然而然的這么理解,
但是我們一定要注意在什麼時候不能這么理解。只要記住什麼時候不能這么理解,我們就不會因為
這種「近似」的理解方式而犯錯,而同時從這種理解方式里得到了方便和好處。
把引用直接當作對象本身的好處是簡單直接,容易理解,而「誤差」的地方就在於,假設只有這個引用
可以修改此對象。換句話說,當別的引用修改了對象的時候,我們毫不知情並很感費解。比如:
String name=null;
HashMap map=new HashMap();
map.put("name",name);
//do a lot of things
name="hyq";
當我們再從map里取出name的時候,發現它已經被賦值為hyq了!放進去的時候明明是啥都沒有啊!
咋就變了訥?
引用到name那個對象的不只你map一個阿!
在同一個函數里出現這種情況還不是很常見,我們一般也不必這么寫,更多的是出現在函數調用、傳參的時候,這樣更加隱蔽,不易發現,也讓代碼可讀性下降。比如:
String name=null;
HashMap map=new HashMap();
map.put("name",name);
alterName(name);
在alterName函數里我們修改了name對象,這會直接影響到函數外的map。
所以,當我們把引用和對象故意混淆時,一定要記住什麼時候應該分清楚。
對象的使用不外乎以下幾種情況:
1
String name=new String("hyq");
然後使用name,引用生命周期一結束,對象失效(無法被取用)了事。這里只有name一個引用指向此對象,隨便怎麼弄都不會出事。
2
String name=new String("hyq");
String anotherName=name;
這里假設只有name會修改對象,並且在anotherName引用此對象前做完所有修改,anotherName只是取用這個對象調用方法。在這種情況下,也不會出事。這也是我們經常遇到的情況,並且一般都是在函數調用傳參時出現。注意傳參實際上就是String anotherName=name;
這里尤其要注意的是2個引用的生命周期:name修改對象的時候另一個引用還沒出世,而等它出世後
發現它又不會修改對象,怎一個爽字了得!
3
String name=new String("hyq");
String anotherName=name;
代碼和上面一樣,但是這里要麼2個引用都會修改對象,要麼只有一個修改但會影響到另一個。這個時候無論如何你不能再把引用當對象了,你必須分清楚它們。你必須小心仔細,不能有絲毫疏忽。
當然,這種寫法和風格無論如何是不值得提倡的,若非必要(沒辦法)請勿模仿!因為必然有一個引用
在不知情的情況下被人修改了對象,等它用的時候會大吃一驚,而這個對象是在什麼時候被什麼人修改的,極難排查。
(上面例子舉得不好,String類是不變類,汗!)
StringBuffer name=new StringBuffer("hyq");
StringBuffer anotherName=name;
//do a lot of things
anotherName.append("is my gf");
你可能寫得爽,一時痛快就這么寫了,你也知道是什麼人在什麼時候修改了對象,但是別人呢?
要知道,這里可能不是相隔幾行代碼這么簡單,可能是嵌套了好幾層函數調用!你把那個anotherName傳到第5層函數裡面,然後喪心病狂的修改了那個對象,除了天知地知你知,鬼
都看不出來!