Java中值類(lèi)型和引用類(lèi)型詳解
我們都知道java是一種面向?qū)ο蟮木幊陶Z(yǔ)言,但是在實(shí)際意義上java并不是純面向?qū)ο?,因?yàn)槊嫦驅(qū)ο蟮囊饬x就是萬(wàn)物皆對(duì)象,那么如果說(shuō)int類(lèi)型的變量也是一個(gè)對(duì)象的話,那么我們應(yīng)該能用"."這個(gè)東西訪問(wèn)到它的屬性或者是方法,例如:
import java.util.ArrayList; import java.util.List; public class Test { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.get(0); } }
就好比是這樣,我們把這個(gè)list這個(gè)對(duì)象看做一個(gè)變量,如果他是對(duì)象的話那么我們應(yīng)該能夠訪問(wèn)到它的屬性和方法,但是在java中的基本數(shù)據(jù)類(lèi)型是沒(méi)屬性和方法的,那么我們就可以說(shuō),只要點(diǎn)"."不出來(lái)東西的變量都是基本數(shù)據(jù)類(lèi)型(于是就出現(xiàn)了包裝類(lèi)這種東西)。
關(guān)于java中的值類(lèi)型和引用類(lèi)型的方法傳遞問(wèn)題
咱們先看看Java中的這些數(shù)據(jù)是怎么存儲(chǔ)的
不知道兄弟們能不能理解,我在用語(yǔ)言描述一遍
在一個(gè)函數(shù)中兩個(gè)基本類(lèi)型的變量在聲明了之后,將這兩個(gè)變量作為參數(shù)傳遞給另一個(gè)方法,這個(gè)方法會(huì)復(fù)制兩個(gè)副本,也就是說(shuō)在swap(int, int)方法中交換的是兩個(gè)副本的值,其真實(shí)的值并沒(méi)有交換,那么就會(huì)有人想了,那用包裝類(lèi)啊,用引用類(lèi)型的數(shù)據(jù)不就能交換了嗎,咱么看一下:
public class Test { public static void main(String[] args) { Integer n1 = 1, n2 = 2; System.out.println("交換前: num1: " + n1 + "\tnum2: " + n2); swap(n1, n2); System.out.println("交換后: num1: " + n1 + "\tnum2: " + n2); } public static void swap(Integer num1, Integer num2) { Integer temp = num1; num1 = num2; num2 = temp; } }
這個(gè)結(jié)果是沒(méi)有交換的,那么就會(huì)有人想了,這是怎么回事呢?
其實(shí)雖說(shuō)是引用類(lèi)型,但是在傳參數(shù)的過(guò)程中,還是按照副本的方式傳遞的,只不過(guò)是將棧區(qū)中存儲(chǔ)的地址作為副本進(jìn)行交換,但是數(shù)據(jù)在堆中,并沒(méi)有交換。
Oracle官方也說(shuō)過(guò),java是沒(méi)有引用傳遞的,只有值類(lèi)型的按值傳遞和引用類(lèi)型的按值傳遞,說(shuō)白了只有按值傳遞,是無(wú)他將引用進(jìn)行傳遞的。但是C++中是有引用類(lèi)型的,我們來(lái)看一段代碼:
#include <iostream> using namespace std; int main(int agv, char** args) { int num1 = 1, num2 = 2; cout << "交換前 " << "num1: " << num1 << "\tnum2: " << num2 << endl; swap(num1, num2); cout << "交換后 " << "num1: " << num1 << "\tnum2: " << num2 << endl; } void swap(int& num1, int& num2) { int temp = num1; num2 = num1; num2 = temp; }
結(jié)果顯示為:
這個(gè)是C++中的引用類(lèi)型傳遞,傳遞的參數(shù)確確實(shí)實(shí)是數(shù)據(jù)的引用
在C++中或者利用指針進(jìn)行地址中的值交換操作也可以,只不過(guò)相對(duì)來(lái)說(shuō)麻煩一些(其實(shí)這是在C中的操作)輸出結(jié)果和上面的是一樣的
#include <iostream> using namespace std; int main(int agv, char** args) { int num1 = 1, num2 = 2; cout << "交換前 " << "num1: " << num1 << "\tnum2: " << num2 << endl; swap(num1, num2); cout << "交換后 " << "num1: " << num1 << "\tnum2: " << num2 << endl; } void swap(int* num1, int* num2) { int temp = *num1; *num1 = *num2; *num2 = temp;
在C#中也有引用傳遞,需要用到關(guān)鍵字ref,代碼如下
static void Main(string[] args) { int num1 = 1, num2 = 2; Console.WriteLine("交換前: num1: {0}\tnum2: {1}", num1, num2); swap(ref num1, ref num2); Console.WriteLine("交換后: num1: {0}\tnum2: {1}", num1, num2); Console.ReadKey(); } static void swap(ref int num1, ref int num2) { int temp = num1; num1 = num2; num2 = temp; }
輸出結(jié)果為:
確實(shí)也進(jìn)行交換了
說(shuō)了這么多都快跑題了,這時(shí)候可能就有人想 誒 明明標(biāo)題是Java的標(biāo)題,怎么說(shuō)了這么一大堆其他語(yǔ)言的東西,馬上了 不用著急
但是Java這兩個(gè)功能沒(méi)有怎么辦呢?
我們可以用數(shù)組的方式,反正就是想法設(shè)法把堆中的數(shù)據(jù)進(jìn)行交換,或者用返回值的方式,但是返回的話也只能返回一個(gè)數(shù)據(jù)(不像C#中能返回多個(gè)數(shù)據(jù),有人就會(huì)想了,怎么java這么菜,啥啥干不了),但是事實(shí)就是如此,我們又能有什么辦法。。。
public static void main(String[] args) { int[] n1 = {1}, n2 = {2}; System.out.println("交換前: num1: " + n1[0] + "\tnum2: " + n2[0]); swap(n1, n2); System.out.println("交換后: num1: " + n1[0] + "\tnum2: " + n2[0]); } public static void swap(int[] num1, int[] num2) { int temp = num1[0]; num1[0] = num2[0]; num2[0] = temp; }
所以咯,java只能這么進(jìn)行交換了
到此這篇關(guān)于Java中值類(lèi)型和引用類(lèi)型詳解的文章就介紹到這了,更多相關(guān)Java值類(lèi)型和引用類(lèi)型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java IO流將一個(gè)文件拆分為多個(gè)子文件代碼示例
這篇文章主要介紹了java IO流將一個(gè)文件拆分為多個(gè)子文件代碼示例,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12解決Maven中的依賴(lài)導(dǎo)包問(wèn)題(組合技巧)
自從我開(kāi)始接觸了以spring為框架的項(xiàng)目學(xué)習(xí)后,這個(gè)maven導(dǎo)包老是出現(xiàn)問(wèn)題,每次在這個(gè)上面花費(fèi)好多時(shí)間,于是乎打算寫(xiě)一個(gè)秘籍出來(lái),這篇文章主要介紹了解決Maven中的依賴(lài)導(dǎo)包問(wèn)題,需要的朋友可以參考下2023-11-11Java設(shè)計(jì)模式之橋梁(Bridge)模式
這篇文章主要介紹了Java設(shè)計(jì)模式之橋梁(Bridge)模式,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)Java設(shè)計(jì)模式的小伙伴們有很好的幫助,需要的朋友可以參考下2021-05-05Java封裝數(shù)組實(shí)現(xiàn)包含、搜索和刪除元素操作詳解
這篇文章主要介紹了Java封裝數(shù)組實(shí)現(xiàn)包含、搜索和刪除元素操作,結(jié)合實(shí)例形式分析了java針對(duì)數(shù)組元素的查找、刪除、判斷等相關(guān)操作封裝與使用技巧,需要的朋友可以參考下2020-03-03詳解Java中的do...while循環(huán)語(yǔ)句的使用方法
這篇文章主要介紹了Java中的do...while循環(huán)語(yǔ)句的使用方法,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-10-10Java HelloWorld原理分析_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
我們初學(xué)java的第一個(gè)程序是"hello world"。下面通過(guò)實(shí)例代碼給大家講解Java HelloWorld原理分析,感興趣的朋友一起學(xué)習(xí)吧2017-05-05java?Stream流常見(jiàn)操作方法(反射,類(lèi)加載器,類(lèi)加載,反射)
這篇文章主要介紹了java?Stream流常見(jiàn)操作方法(反射,類(lèi)加載器,類(lèi)加載,反射),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定參考價(jià)值,感興趣的小伙伴可以參考一下2022-06-06jvm運(yùn)行原理以及類(lèi)加載器實(shí)例詳解
這篇文章主要給大家介紹了關(guān)于jvm運(yùn)行原理以及類(lèi)加載器的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05