Java基本类型与运算
問題及答案來源自《Java程序員面試筆試寶典》第四章 Java基礎知識 4.4基本類型與運算
?
?
?
1、Java提供了哪些基本數據類型?
Java一共提高了八種原始的數據類型:byte、short、int、long、float、double、char、boolean
基本數據類型不是對象,而是基本數據類型,這些數據類型變量在聲明之后就會立刻在棧上被分配內存空間
?
八種基本類型可以分為以下四類:
- int相關:short(2字節)、int(4字節)、long(8字節)
- float相關:float(4字節)、double(8字節)
- boolean相關:boolean(1字節)、byte(1字節)
- char相關:char(2字節)(unicode字符)
另外Java還提供了對這些原始數據類型的封裝類(字符類型Character、布爾類型Boolean、數值類型Byte、Short、
Integer、Long、Float、Double)
?
封裝類型和原始類型的不同之處:
- 原始類型傳遞參數按值傳遞,封裝類型傳遞參數傳的是引用
- 類實例化時,封裝類型默認值是null,原始類型默認值與它們的類型有關(比如int默認值為0)
?
精度損失:
當把高精度的變量賦值給低精度的變量時會造成精度損失,例如將double類型的數值賦值給float類型的變量
eg:float f = 0.93; 這樣會造成精度損失,正確的方法是采用強制類型轉換,eg:float f = (float)0.93;
?
?
2、什么是不可變類?
不可變類:
不可變類是指當創建了這個類的實例后,就不允許修改它的值,不可變類類似于常量,即只允許別的程序讀,
但是不允許別的程序進行修改
?
常見的不可變類:
基本類型的封裝類(Integer、Float等)、String
?
String類是不可變類,那么下面這段代碼為什么可行?
1 String s = "Hello"; 2 s += " World"; 3 System.out.println(s);解釋:
第2行代碼中修改的只是s的引用,s由原來的指向"Hello"改成指向"Hello World",
原來的"Hello"還存在于內存中并沒有被改變
?
??
3、值傳遞與引用傳遞有哪些區別?
Java語言中參數傳遞有兩種方式:值傳遞和引用傳遞
值傳遞:
在方法調用中,實參把值傳遞給形參,形參只是用實參的值初始化一個臨時的存儲單元,因此形參與
實參雖然值一樣,但是有著不同的存儲單元,對形參的改變不會影響實參的改變
引用傳遞:
在方法調用中,傳遞的是對象(也可以看作是對象的地址),這是形參和實參的對象指向同一塊存儲單元,
因此對形參的修改就會影響實參的值
在Java中,原始數據類型在傳遞參數時按值傳遞,而普通對象在傳遞參數時按引用傳遞
實例如下:
1 public class test { 2 public static void testPassParameter(StringBuffer ss1, int n){ 3 ss1.append(" World"); // 引用 4 n = 8; // 值 5 } 6 7 public static void main(String[] args) { 8 int i = 1; 9 StringBuffer s1 = new StringBuffer("Hello"); 10 testPassParameter(s1, i); 11 System.out.println(s1); // Hello World 12 System.out.println(i); // 1 13 } 14 }?
Java中八種基本數據類型都是按值傳遞,其他所有類型都是按引用傳遞,由于Java中八種基本數據類型的包裝類型
都是不可變類型,因此增加了對按引用傳遞的理解難度,詳細情況看下面的實例:
1 public class test { 2 public static void changeStringBuffer(StringBuffer ss1, StringBuffer ss2) { 3 ss1.append(" World"); 4 ss2 = ss1; 5 } 6 7 public static void main(String[] args) { 8 Integer a = new Integer(1); 9 Integer b = a; 10 b = new Integer(b.intValue() + 1); 11 System.out.println(a + " " + b); // 1 2 第10行代碼實際上是創建了一個新的Integer對象 12 StringBuffer s1 = new StringBuffer("Hello"); 13 StringBuffer s2 = new StringBuffer("Hello"); 14 changeStringBuffer(s1, s2); 15 System.out.println(s1 + " " + s2); // Hello World Hello 16 } 17 }由上面的實例可以看出,按引用傳遞實際上當修改形參中地址對應的內容時,實參會發生相應變化,但是當
直接改變形參地址時實參不會改變,這說明了按引用傳遞實際上也是一種按值傳遞(傳的是地址)
也就是說引用傳遞不會改變實際參數指向的地址,但是能改變實際參數指向的地址中的內容
?
?
4、不同數據類型的轉換有哪些規則?
背景描述:
在Java中,當參與運算的兩個變量的數據類型不同時,就需要進行隱式的數據轉換,規則為從低精度向高精度轉換,
即優先級滿足:byte < short < char < long < float < double,例如不同數據類型的值在進行運算時,short類型數據
能夠自動轉換成int類型,int類型能夠自動轉換成float類型等,反之則需要通過強類型轉換
?
類型自動轉換:
低級數據類型可以自動轉換為高級數據類型,轉換規則如下:
自動轉換的注意事項:
- char類型轉換時會自動轉換成其對應的ASCII碼
- byte、char、short類型的數據在參與運算時會自動轉換成int型,但使用+=運算時不會產生類型轉換
- boolean類型是不能和其他數據類型相互轉換的?
?
強制類型轉換:
當需要從高級數據類型轉換成低級數據類型時,就需要進行強制類型轉換,強制類型轉換如下:
- byte =》char
- char =》byte
- short =》byte、char
- int =》byte、short、char
- long =》byte、short、char、int
- float =》byte、short、char、int、long
- double =》byte、short、char、int、long、float
另外要注意進行強制類型轉換可能會損失精度(高精度轉換成低精度)
?
?
5、強制類型轉換的注意事項有哪些?
Java中的+=是Java中規定的運算法,Java編譯器會對其進行特殊處理,因此語句short s1 = 1; s1 += 1; 能夠編譯通過?
?
?
6、運算符優先級是什么?
?
?
7、Math類中round、ceil和floor方法的功能各是什么?
- round:對數四舍五入
- ceil:對數向上取整
- floor:對數向下取整
下面是測試代碼:
1 public class test { 2 public static void main(String[] args) { 3 float m = 6.4f; 4 float n = -6.4f; 5 System.out.println(Math.round(m)); // 6 6 System.out.println(Math.round(n)); // -6 7 System.out.println("==============="); 8 System.out.println(Math.ceil(m)); //7.0 9 System.out.println(Math.ceil(n)); // -6.0 10 System.out.println("==============="); 11 System.out.println(Math.floor(m)); // 6.0 12 System.out.println(Math.floor(n)); // -7.0 13 System.out.println("==============="); 14 } 15 }?
?
8、++i和i++有什么區別?
在java的執行過程中,i++和++i都直接對i進行了i=i+1的操作,
但是不同的是i++得到的是i未進行加法操作的前的值的副本,而++i直接得到計算后的值
比如a = i++;是將i的值賦值給a然后i的值再+1,而a=++i是將i的值+1然后再將+1后的i的值賦值給a
示例代碼:
1 public class test { 2 public static void main(String[] args) { 3 int i = 1; 4 System.out.println((i++)+(i++)); // 3 5 System.out.println(i); // 3 6 System.out.println((i++)+(++i)); // 8 7 System.out.println(i); // 5 8 System.out.println((i++)+(i++)+(i++)); // 18 9 System.out.println(i); // 8 10 } 11 }?
?
9、無符號數的右移操作?
Java提供了兩種右移運算符:>>和>>>,>>被稱為有符號右移運算符,>>>被稱為無符號右移運算符
兩者的區別:
- >>在右移時,若參與運算的數為正數則在高位補0,若為負數則在高位補1
- >>>則不同,不論參與運算的數字為正數或負數,均會在高位補0
?
引申 - <<運算符和>>運算符有什么異同?
<<運算符標識左移,左移n位表示原來的值乘2的n次方,經常用來代替乘法操作
例如,一個數m乘以16可以表示為將這個數左移4位(m<<4)
由于CPU直接支持位運算,因此位運算比乘法運算的效率更高
與右移運算不同的是左移運算沒有有符號和無符號的區別,在左移時,移除高位的同時在低位補0
?
?
10、char型變量中是否可以存儲一個中文漢字?
在Java中,默認使用unicode編碼方式,即每個字符(char)占用兩個字節,因此char可以存儲中文漢字
String是由char組成的,但它采用了更靈活的方式存儲,即英文占用一個字節,而中文一般占用兩個字節
示例代碼:
1 public class test { 2 public static void getLen(String s){ 3 System.out.println(s + "的長度是: " + s.length() + " 所占字節數是: " + s.getBytes().length); 4 } 5 6 public static void main(String[] args) { 7 String s1 = "hello"; 8 String s2 = "你好"; 9 getLen(s1); 10 getLen(s2); 11 } 12 }注:在Java中,中文字符所占的字節數取決于字符的編碼方式,一般情況下,采用ISO8859-1編碼方式時,
一個中文字符與一個英文字符一樣只占1個字節;采用GB2312或GBK編碼方式時,一個中文字符占2個字節;
而采用UTF-8編碼方式時,一個中文字符會占3個字節
?
轉載于:https://www.cnblogs.com/wyb666/p/10300570.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的Java基本类型与运算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 当当创始人李国庆谈吴秀波事件:呼吁释放陈
- 下一篇: Java Integer的缓存策略