亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

java的一些基本知識(shí)

系統(tǒng) 1766 0

對(duì)象與基本類型

幾乎所有Java 初學(xué)者都被告知,在Java里一切都被視為對(duì)象(Object),操縱對(duì)象的表示符實(shí)際上時(shí)對(duì)象的一個(gè)引用(Reference)。例如

String str; // 注意!此處創(chuàng)建了一個(gè)引用,而非對(duì)象

str=new String(“Hello”);// 這里創(chuàng)建了一個(gè)String 對(duì)象并與str相關(guān)聯(lián)

通常用new 操作符來(lái)創(chuàng)建一個(gè)新對(duì)象,并存儲(chǔ)在堆里面。 【注】具體內(nèi)容可以參看 Java 堆與棧

程序設(shè)計(jì)中有一系列小的、簡(jiǎn)單的變量(筆者是這樣認(rèn)為的),將它們存儲(chǔ)在堆里往往并不是很高效,因此對(duì)于這些基本類型,Java 創(chuàng)建一個(gè)并非引用的“自動(dòng)”的變量,并將其值存儲(chǔ)在棧中。 【注】具體內(nèi)容可以參看 Java 堆與棧

Java 確定了每種基本類型所占存儲(chǔ)空間的大小,并且不隨計(jì)算機(jī)硬件架構(gòu)的變化而變化,因此他們更具可移植性。Java 基本類型及其包裝器的具體信息參見下表:

基本類型

大小

最小值

最大值

包裝器類型

boolean

Boolean

char

16-bit

Unicode o

Unicode 264-1

Character

byte

8 bits

-128

+127

Byte

short

16 bits

-2 15

+2 15 -1

Short

int

32 bits

-2 31

+2 31 -1

Integer

long

64 bits

-2 63

+2 63 -1

Long

float

32 bits

IEEE754

IEEE754

Float

double

64 bits

IEEE754

IEEE754

Double

void

Void

基本類型具有的包裝器類型使得可以在堆中創(chuàng)建一個(gè)非基本對(duì)象用來(lái)表示對(duì)應(yīng)的基本類型,例如

Character ch=new Character( ‘c ’);

Java SE5 的自動(dòng)包裝功能將自動(dòng)的將基本類型轉(zhuǎn)換為包裝器類型:

Character ch= ‘c ’;//Autoboxing

可以看到Java SE5 的自動(dòng)包裝功能為我們提供了很大的方便(泛型中你會(huì)看到它的優(yōu)勢(shì)),然而如果你不了解它的工作原理則會(huì)讓你陷入意想不到的困惑和麻煩之中。請(qǐng)看下面的例子:

      
public static void main(String args[]) { Integer i1 = 127 ; Integer i2 = 127 ; System.out.println(i1 == i2); i1 = 128 ; i2 = 128 ; System.out.println(i1 == i2); } /* Output: * true * false */

有些令人驚訝,兩個(gè)范例語(yǔ)法完全一樣,只不過(guò)改個(gè)數(shù)值而已,結(jié)果卻相反。這是因?yàn)樵谧詣?dòng)包裝時(shí)對(duì)于從–128 到127之間的值,它們被包裝為Integer對(duì)象后,會(huì)存在內(nèi)存中被重用,而其它的值,被包裝后的Integer對(duì)象并不會(huì)被重用,即相當(dāng)于每次包裝時(shí)都新建一個(gè)Integer對(duì)象。

然而下面的輸出卻是ture ,這是因?yàn)槟阌昧薾1=n2,n1只是n2的別名而已。

在看一個(gè)例子:

      
public static void main(String args[]) { Integer i1 = 12 ; Integer i2 = 12 ; System.out.println(i1 == i2); i1 = new Integer( 13 ); i2 = new Integer( 13 ); System.out.println(i1 == i2); i1 = i2 = new Integer( 14 ); System.out.println(i1 == i2); } /* Output: * true * false * true */

天吶!數(shù)字13 仿佛被詛咒了一般,==對(duì)它的判斷似乎失去了效用!事實(shí)上可憐的Java一無(wú)所知,如果你對(duì)輸出的結(jié)果感到疑惑,說(shuō)明你對(duì)==和Java的存儲(chǔ)還不是很了解。


回頁(yè)首

== 與equals()

如果知道下面的規(guī)則,你對(duì)上面例子的輸出結(jié)果或許就不會(huì)那么疑惑了:

1. 對(duì)于基本類型,== 將比較兩邊的值是否相等;

2. 對(duì)于對(duì)象,== 則比較對(duì)象的是否指向同一個(gè)對(duì)象。

如果你仍然對(duì)輸出結(jié)果不甚明白,那么別急,關(guān)于Java 堆與棧的介紹將會(huì)讓你明了,但是在這里我還要添加關(guān)于equals()的介紹。

或許你已經(jīng)被告知,要想比較對(duì)象的實(shí)際內(nèi)容是否相同必須使用所有對(duì)象都適用的特殊方法equals() ,例如:

Integer n1=new Integer(13);

Integer n2=new Integer(13);

System.out.println(n1.equals(n2)); //true

這看上去的確很簡(jiǎn)單,但是下面的例子中equals() 又要讓你失望和疑惑了:

public class Value { public int i;}

Value v1=new Value();

Value v2=new Value();

v1.i=v2.i=13;

System.out.println(v1.equals(v2)); //false

哦,它輸出了false !好吧,讓我們看看equals()方法的原型:

      
public boolean equals(Object obj) { return ( this == obj); }

再讓我們看看Integer 中的equals()方法:

      
public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false ; }

OK! 一切都清楚了,繼承自O(shè)bject 中的equals()方法與==沒什么兩樣,只是Integer類對(duì)equals()方法進(jìn)行了重寫而已,這樣我們很容易能寫出令上面例子中System.out.println(v1.equals(v2));語(yǔ)句輸出true的方法


回頁(yè)首

Java 堆與棧

Java 的堆是一個(gè)位于隨機(jī)訪問(wèn)存儲(chǔ)器(RAM )的運(yùn)行時(shí)數(shù)據(jù)區(qū)。通常使用new操作符在堆中創(chuàng)建對(duì)象,它們不需要程序代碼來(lái)顯式的釋放。堆是由垃圾回收來(lái)負(fù)責(zé)的,堆的優(yōu)勢(shì)是可以動(dòng)態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,因?yàn)樗窃谶\(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存的,Java的垃圾收集器會(huì)自動(dòng)收走這些不再使用的數(shù)據(jù)。但缺點(diǎn)是,由于要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存,存取速度較慢。

Java 的棧也位于RAM ,它的存取速度比堆要快,僅次于寄存器且據(jù)可以共享,主要存放一些基本類型的變量和對(duì)象的引用;但存在于棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性。

棧有一個(gè)很重要的特殊性,就是存在棧中的數(shù)據(jù)可以共享。假設(shè)我們同時(shí)定義:

int a = 3;

int b = 3

編譯器先處理int a = 3 ;首先它會(huì)在棧中創(chuàng)建一個(gè)變量為a的引用,然后查找棧中是否有3這個(gè)值,如果沒找到,就將3存放進(jìn)來(lái),然后將a指向3。接著處理int b = 3;在創(chuàng)建完b的引用變量后,由于在棧中查找到3這個(gè)值,便將b直接指向3。這樣,就出現(xiàn)了a與b同時(shí)均指向3的情況。

這時(shí),如果再令a=4 ;那么編譯器會(huì)重新搜索棧中是否有4值,如果沒有,則將4存放進(jìn)來(lái),并令a指向4;如果已經(jīng)有了,則直接將a指向這個(gè)地址。因此a值的改變不會(huì)影響到b的值。

好了,我們?cè)賮?lái)看上面的例子:

Integer i1 = 12;

Integer i2 = 12;

System.out.println(i1==i2); //true

由于是自動(dòng)包裝,對(duì)于從–128 到127之間的值,它們被包裝為Integer對(duì)象后,會(huì)存在內(nèi)存中被重用,因此輸出的是true;

i1=new Integer(13);

i2=new Integer(13);

System.out.println(i1==i2); //flase

由于使用的是new 操作符,而不是自動(dòng)包裝功能,Java在堆里面創(chuàng)建了兩個(gè)Integer對(duì)象,分別與i1和i2關(guān)聯(lián),由于==對(duì)于對(duì)象比較的是引用,所以輸出是false;

然而下面的語(yǔ)句中實(shí)際上只創(chuàng)建了一個(gè)對(duì)象,這里又出現(xiàn)的別名的現(xiàn)象

i1=i2=new Integer(14);

System.out.println(i1==i2);

因此用第一種方式創(chuàng)建多個(gè)int, 在內(nèi)存中其實(shí)只存在一個(gè)對(duì)象而已.這種寫法有利與節(jié)省內(nèi)存空間.同時(shí)它可以在一定程度上提高程序的運(yùn)行速度,因?yàn)镴VM會(huì)自動(dòng)根據(jù)棧中數(shù)據(jù)的實(shí)際情況來(lái)決定是否有必要?jiǎng)?chuàng)建新對(duì)象。而對(duì)于Integer i = new Integer (int);的代碼,則一概在堆中創(chuàng)建新對(duì)象,而不管其字符串值是否相等,是否有必要?jiǎng)?chuàng)建新對(duì)象,從而加重了程序的負(fù)擔(dān)。

好了,這樣以來(lái)相信下面的程序也不會(huì)為我們帶來(lái)太多的疑惑了:

      
public static void main(String args[]) { Integer i1 = new Integer( 13 ); Integer i2 = new Integer( 13 ); int i3 = 13 ; System.out.println(i1 == i2); System.out.println(i2 == i3); System.out.println(i3 == i1); } /* Output * false * true * true */


回頁(yè)首

賦值

賦值操作符“= ”對(duì)我們來(lái)說(shuō)是再熟悉不過(guò)的了。它取右邊的值(右值)復(fù)制給左邊的值(左值),左值必須是一個(gè)明確的已命名的變量。例如:

Integer n1=new Integer(13);

Integer n2=new Integer(14);

n2=n1; // 別名現(xiàn)象

n2=11;

System.out.println(n1); //11

了解了Java 的存儲(chǔ)分配就不難知道,對(duì)于基本類型復(fù)制的是值,對(duì)于對(duì)象復(fù)制的則是對(duì)象的引用。

進(jìn)行賦值的時(shí)候Java 編譯器會(huì)自動(dòng)檢查左值和右值的類型是否匹配,必要的時(shí)候會(huì)洗的進(jìn)行類型轉(zhuǎn)換。

一方面Java 中允許我們顯式的進(jìn)行類型轉(zhuǎn)換,例如:

int i=(int)1.7; //i 的值1 ,如例子所示將浮點(diǎn)類型轉(zhuǎn)化為整型是Java總是對(duì)數(shù)字執(zhí)行截尾而非舍入

另一方面,編譯器會(huì)自動(dòng)進(jìn)行類型的提升,例如:

int i=13;

long l=i;

Java 的自動(dòng)提升確實(shí)提供了一定的便利,然而更多的是讓我們陷入一種迷茫之中,例如:

short s=1;

s=s+1;

運(yùn)行的時(shí)候編譯器會(huì)提示“可能損失精度”。首先在s=s+1; 語(yǔ)句中由于Java將整型常量1默認(rèn)為int類型,編譯器會(huì)自動(dòng)將s提升為int與1相加之后返回int類型,而s為short類型,則需要進(jìn)行窄化轉(zhuǎn)換,并造成“可能損失精度“。

然而下面的語(yǔ)句卻能順利的通過(guò):

short s=1;

s+=1;

許多程序員都會(huì)認(rèn)為E1 op = E2 只是E1 = E1 op E2)的簡(jiǎn)寫方式,而事實(shí)上中講到,復(fù)合賦值E1 op= E2等價(jià)于簡(jiǎn)單賦值E1 = (T)((E1)op(E2)),其中T是E1的類型,除非E1只被計(jì)算一次(參見《Java語(yǔ)言規(guī)范)。可以看到復(fù)合賦值幫我們進(jìn)行了顯式的類型轉(zhuǎn)換。

再來(lái)看下面的例子,

      
public static void main(String args[]) { int a = 3 ; int b = 7 ; a ^= b ^= a ^= b; System.out.println( " a= " + a + " b= " + b); } /* Output: * a=0 b=3 */

如果你了解C 語(yǔ)言,那么上述表達(dá)式是交換兩個(gè)int類型數(shù)據(jù)的方法之一,然而這在Java中卻不管用,得到的結(jié)果卻是a=0 b=3;

《Java 語(yǔ)言規(guī)范》描述到:操作符的操作數(shù)是從左向右求值的。為了求表達(dá)式x ^= expr的值,x的值是在計(jì)算expr之前被提取的,并且這兩個(gè)值的異或結(jié)果被賦給變量x。因此Java中a^=b^=a^=b;的實(shí)際行為:

      
int tmp1 = a ; // a在表達(dá)式中第一次出現(xiàn) int tmp2 = b ; // b的第一次出現(xiàn) int tmp3 = a ^ b ; // 計(jì)算a ^ b a = tmp3 ; // 最后一個(gè)賦值:存儲(chǔ)a ^ b 到 a b = tmp2 ^ tmp3 ; // 第二個(gè)賦值:存儲(chǔ)最初的a值到b中 a = tmp1 ^ b ; // 第一個(gè)賦值:存儲(chǔ)0到a中

回頁(yè)首

參考資料

1. 《Thinking in Java, Second Edition 》,Bruce Eckel,Prentice Hall

2. 《Java Puzzlers : Traps, Pitfalls, and Corner Cases 》,Joshua Bloch,Neal Gafter,Addison Wesley/Pearson

3. 《The Java Language Specification 》,James Gosling,bill Joy,Guy Steele,Addison-Wesley Professional

java的一些基本知識(shí)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 日韩精品一区二区三区免费观看 | 在线看v| 精品国产九九 | 99热播 | 国产精品成人观看视频免费 | 深夜影院在线 | 香蕉综合在线 | 精品国产香蕉 | 日韩精品一区二区在线观看 | 麻豆国产在线观看一区二区 | 在线亚洲播放 | 日韩 亚洲 欧美 中文 高清 | 国产福利视频网站 | 国产精品久久久久三级 | 天天爽天天干天天操 | 国产91在线免费 | 九九国产视频 | 香蕉综合网| 丰满放荡岳乱妇91www | 日日操日日 | 欧美三级美国一级 | 久久中文字幕免费视频 | 视频二区中文字幕 | 写真福利 第 页 在线视频 | 亚洲人体视频 | 久久国产精品国产精品 | 久久亚洲精品人成综合网 | 91在线视频免费观看 | 精品久久久久久久 | 久久亚洲国产中v天仙www | 毛片a级| 香蕉福利 | 成人免费www在线高清观看 | 色香欲综合成人免费视频 | 天天做天天爽爽快快 | 黄色自拍网站 | 中文字幕在线观看第二页 | 久久精品国产精品亚洲综合 | 在线视频日韩精品 | 久草视频在线资源 | 国产精品欧美久久久久天天影视 |