JAVA基礎知識之數據類型

JAVA的數據類型知識點主要包括基本數據類型,包裝類,字符串類(String,StringBuffer, StringBuilder區別和用法),數組,數據類型轉換等等,暫時只想到這麼多,後面會再補充。面試

1.基本數據類型

重點是JAVA變量分爲原始變量和包裝變量,另外變量初始化時要注意變量類型能表示的範圍以及精度的損失。算法

a.八種基本類型爲 byte(8bit), short, int(32bit), long, float, double, boolean, char編程

b.對應封裝類型爲Byte,Short,Integer,Long,Float,Double,Boolean,Character數組

c.Java中的數值類型都是有符號的,取值範圍是固定的,不隨硬件環境和操做系統改變。安全

d.封裝類和原始類型有如下不一樣點多線程

  • 原始類型作參數傳遞時是值傳遞,封裝類型是按引用傳遞
  • 封裝類的對象初始值是null,但原始類型的變量的默認值不是。(int默認初始化爲0)

e.Java中直接寫的小數是double類型,直接寫的整數是int類型,所以要注意類型轉換時的精度損失以及表示範圍,例如app

  • float f = 3.4 是會有精度損失的,正確寫法是 float f = (float)3.4 或者 float f = 3.4F
  • int a = 3; long b = a;  int類型沒法表示一個很是大的數,應寫成  long b = aL 或者 long b = (long) a   ???

f.null表示什麼?如何理解String x = nullui

null僅僅表示該引用目前沒有指向任何對象,編譯器不會分配內存, null是將引用變量的值置0. 
編碼

字符串類

Java字符串存儲機制(內存分配方式)

對於String s1 = new String("abc"); String s2 = new String("abc"); 操作系統

兩個引用對象s1和s2雖然內容相同都是"abc",可是s1和s2指向堆內存中不一樣的對象。


 

對於String s1 = "abc"; String s2 = "abc"

s1和s2引用的是同一個常量池中的對象,即,若是常量"abc"的對象已經存在【判斷依據是equals(Object obj)的返回值】,則不會建立新的對象。

總結以下

String s1 = "abc";// s1指向常量區字符串對象"abc"

String s2 = "abc";// s2也指向常量區字符串對象"abc", s1和s2指向的是常量區的同一個對象,所以這裏不會建立新對象

String s3 = new String("abc");// s3指向在堆中建立的新對象,此對象內容爲abc

String s4 = new String("abc");// s4指向在堆中建立的另外一個新對象,此對象內容爲常量區的abc,可是s3和s4各自指向堆中不一樣的對象


典型面試題:

1.String s = null 和String s = ""是否相同?

答,不一樣。對於s = null,是定義一個字符串類型的引用,可是它不指向任何一個字符串對象。

對於s = ""; s是一個字符串的引用,它指向了另外一個字符串對象,並且那個對象的內容爲"",即空串。


2. new String("abc") 建立了幾個對象

答,一個或兩個。new會建立一個。另外,若是常量池中已經有"abc"字符串,就不會再在常量區建立一個字符串對象,反之若是常量區尚未"abc"字符串對象,就會在常量區再建立一個字符串abc。


字符串的比較 == , equals 和 hashCode

== 用來直接比較兩個變量對應的值是否相等

例如,若是兩個變量都是基本類型的變量,則是直接比較他們的值是否相等,若是兩個變量指向的是對象類型的變量,則是比較這兩個對象的首地址是否相等。

equals一般用來比較對象

equals方法是能夠被子類覆蓋的,若是沒有覆蓋,默認equals也是用==的方式作比較,比較的是對象首地址,首地址相同,則這兩個對象是同一個對象。

而被覆蓋後的方法就不必定了,例如String類中的equals,是比較對象指向的內容,而不是比較對象的首地址。

因此對於 String s1 = new String("abc");String s2 = new String("abc");  s1==s2  爲false, 可是 s1.equals(s2)爲true.

hashCode,若是hashCode沒有被重寫過,就返回該對象地址的編碼值,不然是用來返回一個對象編碼後的int值

那麼爲何須要重寫hashCode呢,這是爲了保證與hash有關的集合類數據的一致性(HashSet, HashMap等)

首先來看看hashSet的put流程,先判斷對象的hashCode在HashSet中是否已經存在,若是不存在,則存入對象;若是存在,則在用equals

判斷一下該對象和存在的對象是否相等,若是相等,則再也不插入;若是不相等,則根據具體算法將對象存放其餘地方。(相同hashCode索引的對象,按鏈表存放?)


那麼如今的問題是,在HashSet中,判斷兩個對象是否相等是用equals的,這要求在equals判斷相等時,hashCode也必須相等才能在邏輯上符合對象相等。

假如兩個對象經過equals相等,可是hashCode不相等,那麼在HashSet中就會出現重複對象,這是不符合HashSet特徵的。

因此就要求,在重寫了equals方法以後,也必須重寫hashCode方法,使得equals與hashCode符合下面的要求,

對於equals()相等的兩個對象,其hashCode()返回的值必定相等

同時還能獲得,對於equals不相等等兩個對象,其hashCode可能相等,也可能不等(參見前面Hash容器存儲原理)


String, StringBuffer, StringBuilder的區別

String

String是不可變類,一旦建立則不能夠修改。String在實例化時能夠用構造方式或者賦值方式。

StringBuffer

對象建立後仍然能夠修改值。若是要修改String對象的值(內容),值能借助StringBuffer間接實現,可是會產生額外臨時對象,影響效率。

String修改原理以下。

String s = "hellow"; s+="World";

以上代碼等價爲:

StringBuffer sb = new StringBuffer(s);

sb.append("world"); s = sb.toString();

下面來驗證這個結論:

String s= "hellow"; 

String stmp = s;

s+="World";

System.out.println(stmp==s);//輸出false


第二個

 

StringBuffer sb = new StringBuffer("hellow");

StringBuffer sbtmp = sb;

sb.append("world"); 

System.out.println(sbtmp==sb);//輸出true

 

StringBuilder

與StringBuffe類似,都支持字符串修改,都在字符串緩衝區進行。區別是StringBuilder不是線程安全的。

所以這三個字符串類的執行效率是 StringBuilder >  StringBuffer > String.

所以若是操做數據比較少,優先用String,若是單線程下數據量比較大,優先用StringBuilder, 若是在多線程下操做大量數據,則用StringBuffer.


 

數組

 

  • Java中數組是否是對象:Java中的數組不只有屬性(length等),也有本身的方法(clone等),從這個角度來講JAVA數組是對象。
  • JAVA數組的初始化
  • type arrayName[];  或者  type[] arrayName
  • 與C++不一樣的是,JAVA數組被建立後會默認初始化,例如int類型會將元素初始化爲0,對象則會初始化爲nll
  • JAVA數組在定義時,不會爲數組元素分配存儲空間,所以[]中不須要指定長度。而在使用時須要分配空間,例如: arrayName = new type[size]
  • length屬性與length()方法的區別
  • length屬性用來獲取數組的長度
  • length()方法用來計算字符串長度。

 


數據類型轉換


基本數據類型轉換

JAVA基本數據類型轉換分兩種

1.自動轉換

從存儲範圍小的類型到存儲範圍大的類型

自動轉換也叫隱式轉換,由JVM自動完成,不須要額外編程,

具體規則爲:byte→short(char)→int→long→float→double

例如: byte b = 10; short sh = b;   byte自動向short類型轉換


2.強制轉換

從存儲範圍大的類型到存儲範圍小的類型

須要顯示地進行類型轉換,

具體規則爲:double→float→long→int→short(char)→byte

例如  double d = 3.10; int n = d;   double強制轉換成int,(雖然沒有語法錯誤了,可是仍是會有精度損失,不一樣類型損失精度也不一樣)

注意,默認狀況直接寫小數,JVM會認爲是double類型,直接寫整數,會默認爲int類型,

因此 float f = 3.4是沒法經過編譯的,須要寫成 float f = (float)3.4, 或者 float f = 3.4F;

short sh = 5也是沒法經過編譯的,要寫成short sh = (short)5;


基本數據類型和包裝類之間的轉換

string->byte
Byte static byte parseByte(String s)
 
byte->string
Byte static String toString(byte b)
 
char->string
Character static String to String (char c)
 
string->Short
Short static Short parseShort(String s)
 
Short->String
Short static String toString(Short s)
 
String->Integer
Integer static int parseInt(String s)
 
Integer->String
Integer static String tostring(int i)
 
String->Long
Long static long parseLong(String s)
 
Long->String
Long static String toString(Long i)
 
String->Float
Float static float parseFloat(String s)
 
Float->String
Float static String toString(float f)
 
String->Double
Double static double parseDouble(String s)

Double->String
Double static String toString(Double)

基本

相關文章
相關標籤/搜索