Java語言提供了八種基本類型。六種數字類型(四個整數型(默認是int 型),兩個浮點型(默認是double 型)),一種字符類型,還有一種布爾型。
1.基本數據類型
byte:
byte數據類型是8位、有符號的,以二進制補碼表示的整數;(256個數字),占1字節(jié)
最小值是-128(-2^7);
最大值是127(2^7-1);
默認值是0;
byte類型用在大型數組中節(jié)約空間,主要代替整數,因為byte變量占用的空間只有int類型的四分之一;
例子:byte a = 100,byte b = -50。
short:
short數據類型是16位、有符號的以二進制補碼表示的整數,占2字節(jié)
最小值是-32768(-2^15);
最大值是32767(2^15 - 1);
Short數據類型也可以像byte那樣節(jié)省空間。一個short變量是int型變量所占空間的二分之一;
默認值是0;
例子:short s = 1000,short r = -20000。
int:
int數據類型是32位、有符號的以二進制補碼表示的整數;占4字節(jié)
最小值是-2,147,483,648(-2^31);
最大值是2,147,485,647(2^31 - 1);
一般地整型變量默認為int類型;
默認值是0;
例子:int a = 100000, int b = -200000。
long:
long數據類型是64位、有符號的以二進制補碼表示的整數;占8字節(jié)
最小值是-9,223,372,036,854,775,808(-2^63);
最大值是9,223,372,036,854,775,807(2^63 -1);
這種類型主要使用在需要比較大整數的系統(tǒng)上;
默認值是0L;
例子: long a = 100000L,int b = -200000L。
long a=111111111111111111111111(錯誤,整數型變量默認是int型)
long a=111111111111111111111111L(正確,強制轉換)
float:
float數據類型是單精度、32位、符合IEEE 754標準的浮點數;占4字節(jié) ? ?-3.4*E38- 3.4*E38。。。浮點數是有舍入誤差的
float在儲存大型浮點數組的時候可節(jié)省內存空間;
默認值是0.0f;
浮點數不能用來表示精確的值,如貨幣;
例子:float f1 = 234.5f。
float f=6.26(錯誤 ?浮點數默認類型是double類型)
float f=6.26F(轉換正確,強制)
double d=4.55(正確)
double:
double數據類型是雙精度、64位、符合IEEE 754標準的浮點數;
浮點數的默認類型為double類型;
double類型同樣不能表示精確的值,如貨幣;
默認值是0.0d;
例子:double d1 = 123.4。
boolean:
boolean數據類型表示一位的信息;
只有兩個取值:true和false;
這種類型只作為一種標志來記錄true/false情況;
默認值是false;
例子:boolean one = true。
char:
char類型是一個單一的16位Unicode字符;用 ‘’表示一個字符。。java 內部使用Unicode字符集。。他有一些轉義字符 ?,2字節(jié)
最小值是’\u0000’(即為0);
最大值是’\uffff’(即為65,535);可以當整數來用,它的每一個字符都對應一個數字
2. 數據類型之間的轉換
1).簡單類型數據間的轉換,有兩種方式:自動轉換和強制轉換,通常發(fā)生在表達式中或方法的參數傳遞時。
自動轉換
具體地講,當一個較"小"數據與一個較"大"的數據一起運算時,系統(tǒng)將自動將"小"數據轉換成"大"數據,再進行運算。而在方法調用時,實際參數較"小",而被調用的方法的形式參數數據又較"大"時(若有匹配的,當然會直接調用匹配的方法),系統(tǒng)也將自動將"小"數據轉換成"大"數據,再進行方法的調用,自然,對于多個同名的重載方法,會轉換成最"接近"的"大"數據并進行調用。這些類型由"小"到"大"分別為 (byte,short,char)--int--long--float—double。這里我們所說的"大"與"小",并不是指占用字節(jié)的多少,而是指表示值的范圍的大小。
①下面的語句可以在Java中直接通過:
byte b;int i=b; long l=b; float f=b; double d=b;
②如果低級類型為char型,向高級類型(整型)轉換時,會轉換為對應ASCII碼值,例如
char c='c'; int i=c;
System.out.println("output:"+i);輸出:output:99;
③對于byte,short,char三種類型而言,他們是平級的,因此不能相互自動轉換,可以使用下述的強制類型轉換。
short i=99 ; char c=(char)i; System.out.println("output:"+c);輸出:output:c;
強制轉換
將"大"數據轉換為"小"數據時,你可以使用強制類型轉換。即你必須采用下面這種語句格式: int n=(int)3.14159/2;可以想象,這種轉換肯定可能會導致溢出或精度的下降。
2)表達式的數據類型自動提升, 關于類型的自動提升,注意下面的規(guī)則。
①所有的byte,short,char型的值將被提升為int型;
②如果有一個操作數是long型,計算結果是long型;
③如果有一個操作數是float型,計算結果是float型;
④如果有一個操作數是double型,計算結果是double型;
例, byte b; b=3; b=(byte)(b*3);//必須聲明byte。
3)包裝類過渡類型轉換
一般情況下,我們首先聲明一個變量,然后生成一個對應的包裝類,就可以利用包裝類的各種方法進行類型轉換了。例如:
①當希望把float型轉換為double型時:
float f1=100.00f;
Float F1=new Float(f1);
double d1=F1.doubleValue();//F1.doubleValue()為Float類的返回double值型的方法
②當希望把double型轉換為int型時:
double d1=100.00;
Double D1=new Double(d1);
int i1=D1.intValue();
簡單類型的變量轉換為相應的包裝類,可以利用包裝類的構造函數。即:Boolean(boolean value)、Character(char value)、Integer(int value)、Long(long value)、Float(float value)、Double(double value)
而在各個包裝類中,總有形為××Value()的方法,來得到其對應的簡單類型數據。利用這種方法,也可以實現不同數值型變量間的轉換,例如,對于一個雙精度實型類,intValue()可以得到其對應的整型變量,而doubleValue()可以得到其對應的雙精度實型變量。
4)字符串與其它類型間的轉換
其它類型向字符串的轉換
①調用類的串轉換方法:X.toString();
②自動轉換:X+"";
③使用String的方法:String.volueOf(X);
字符串作為值,向其它類型的轉換
①先轉換成相應的封裝器實例,再調用對應的方法轉換成其它類型
例如,字符中"32.1"轉換double型的值的格式為:new Float("32.1").doubleValue()。也可以用:Double.valueOf("32.1").doubleValue()
②靜態(tài)parseXXX方法
String s = "1";
byte b = Byte.parseByte( s );
short t = Short.parseShort( s );
int i = Integer.parseInt( s );
long l = Long.parseLong( s );
Float f = Float.parseFloat( s );
Double d = Double.parseDouble( s );
③Character的getNumericValue(char ch)方法
5)Date類與其它數據類型的相互轉換
整型和Date類之間并不存在直接的對應關系,只是你可以使用int型為分別表示年、月、日、時、分、秒,這樣就在兩者之間建立了一個對應關系,在作這種轉換時,你可以使用Date類構造函數的三種形式:
①Date(int year, int month, int date):以int型表示年、月、日
②Date(int year, int month, int date, int hrs, int min):以int型表示年、月、日、時、分
③Date(int year, int month, int date, int hrs, int min, int sec):以int型表示年、月、日、時、分、秒
在長整型和Date類之間有一個很有趣的對應關系,就是將一個時間表示為距離格林尼治標準時間1970年1月1日0時0分0秒的毫秒數。對于這種對應關系,Date類也有其相應的構造函數:Date(long date)。
獲取Date類中的年、月、日、時、分、秒以及星期你可以使用Date類的getYear()、getMonth()、getDate()、getHours()、getMinutes()、getSeconds()、getDay()方法,你也可以將其理解為將Date類轉換成int。
而Date類的getTime()方法可以得到我們前面所說的一個時間對應的長整型數,與包裝類一樣,Date類也有一個toString()方法可以將其轉換為String類。
有時我們希望得到Date的特定格式,例如20020324,我們可以使用以下方法,首先在文件開始引入,
import java.text.SimpleDateFormat;
import java.util.*;
java.util.Date date = new java.util.Date();
//如果希望得到YYYYMMDD的格式
SimpleDateFormat sy1=new SimpleDateFormat("yyyyMMDD");
String dateFormat=sy1.format(date);
//如果希望分開得到年,月,日
SimpleDateFormat sy=new SimpleDateFormat("yyyy");
SimpleDateFormat sm=new SimpleDateFormat("MM");
SimpleDateFormat sd=new SimpleDateFormat("dd");
String syear=sy.format(date);
String smon=sm.format(date);
String sday=sd.format(date);
總結:只有boolean不參與數據類型的轉換
(1).自動類型的轉換:a.常數在表數范圍內是能夠自動類型轉換的
b.數據范圍小的能夠自動數據類型大的轉換(注意特例)
int到float,long到float,long到double 是不會自動轉換的,不然將會丟失精度
c.引用類型能夠自動轉換為父類的
d.基本類型和它們包裝類型是能夠互相轉換的
(2).強制類型轉換:用圓括號括起來目標類型,置于變量前
3.Java引用類型
Java有 5種引用類型(對象類型):類 接口 數組 枚舉 標注
引用類型:底層結構和基本類型差別較大
JVM的內存空間:(1). Heap 堆空間:分配對象 new Student()
(2). Stack 棧空間:臨時變量 Student stu
(3).Code 代碼區(qū) :類的定義,靜態(tài)資源 Student.class
eg:Student stu = new Student(); //new 在內存的堆空間創(chuàng)建對象
stu.study(); //把對象的地址賦給stu引用變量
上例實現步驟:a.JVM加載Student.class 到Code區(qū)
???? b.new Student()在堆空間分配空間并創(chuàng)建一個Student實例
???? c.將此實例的地址賦值給引用stu, 棧空間
4.負數的二進制表示法
一:表示法:
假設有一個 int 類型的數,值為5,那么,我們知道它在計算機中表示為:
00000000 00000000 00000000 00000101
5轉換成二制是101,不過int類型的數占用4字節(jié)(32位),所以前面填了一堆0。
現在想知道,-5在計算機中如何表示?在計算機中,負數以原碼的補碼形式表達。
一個正數,按照絕對值大小轉換成的二進制數;一個負數按照絕對值大小轉換成的二進制數,然后最高位補1,稱為原碼。
比如 00000000 00000000 00000000 00000101 是 5的 原碼。
?????10000000 00000000 00000000 00000101 是 -5的 原碼。
???備注:
???比如byte類型,用2^8來表示無符號整數的話,是0 - 255了;如果有符號, 最高位表示符號,0為正,1為負,那么,正常的理解就是 -127 至 +127 了.這就是原碼了,值得一提的是,原碼的弱點,有2個0,即+0和-0(10000000和00000000);還有就是,進行異號相加或同號相減時,比較笨蛋,先要判斷2個數的絕對值大小,然后進行加減操作,最后運算結果的符號還要與大的符號相同;于是,反碼產生了。
正數的反碼與原碼相同,負數的反碼為對該數的原碼除符號位外各位取反[每一位取反(除符號位)]。
取反操作指:原為1,得0;原為0,得1。(1變0; 0變1)
比如:正數00000000 00000000 00000000 00000101??的反碼還是 00000000 00000000 00000000 00000101
??????負數10000000 00000000 00000000 00000101??的反碼則是 11111111 11111111 11111111 11111010。
反碼是相互的,所以也可稱:10000000 00000000 00000000 00000101 和 11111111 11111111 11111111 11111010互為反碼。
備注:還是有+0和-0,沒過多久,反碼就成為了過濾產物,也就是,后來補碼出現了。
正數的補碼與原碼相同,負數的補碼為對該數的原碼除符號位外各位取反,然后在最后一位加1.
比如:10000000 00000000 00000000 00000101 的補碼是:11111111 11111111 11111111 11111010。
那么,補碼為:
11111111 11111111 11111111 11111010 + 1 = 11111111 11111111 11111111 11111011
備注:1、從補碼求原碼的方法跟原碼求補碼是一樣的 ,也可以通過完全逆運算來做,先減一,再取反。
??????2、補碼卻規(guī)定0沒有正負之分
所以,-5 在計算機中表達為:11111111 11111111 11111111 11111011。轉換為十六進制:0xFFFFFFFB。
5.位運算
原文:https://blog.csdn.net/xiaochunyong/article/details/7748713
1、左移( <<?)
Test1、將5左移2位:
public class Test {
public static void main(String[] args) {
System.out.println(5<<2);//運行結果是20
}
}
運行結果是20,但是程序是怎樣執(zhí)行的呢?
首先會將5轉為2進制表示形式(java中,整數默認就是int類型,也就是32位):
0000 0000 0000 0000 0000 0000 0000 0101 ? ? ? ? ? 然后左移2位后,低位補0:
0000 0000 0000 0000 0000 0000 0001 0100 ? ? ? ? ? 換算成10進制為20
2、右移(?>>?) ,右移同理,只是方向不一樣罷了(感覺和沒說一樣)
System.out.println(5>>2);//運行結果是1
還是先將5轉為2進制表示形式:
0000 0000 0000 0000 0000 0000 0000 0101 然后右移2位,高位補0:
0000 0000 0000 0000 0000 0000 0000 0001
3、無符號右移(?>>>?)
我們知道在Java中int類型占32位,可以表示一個正數,也可以表示一個負數。正數換算成二進制后的最高位為0,負數的二進制最高為為1
例如 ?-5換算成二進制后為:
1111 1111 1111 1111 1111 1111 1111 1011 ??(剛開始接觸二進制時,不知道最高位是用來表示正負之分的,當時就總想不通。。明明算起來得到的就是一個正數-_-)
我們分別對5進行右移3位、 -5進行右移3位和無符號右移3位:
public class Test {
public static void main(String[] args) {
System.out.println(5>>3);//結果是0
System.out.println(-5>>3);//結果是-1
System.out.println(-5>>>3);//結果是536870911
}
}
我們來看看它的移位過程(可以通過其結果換算成二進制進行對比):
5換算成二進制: 0000 0000 0000 0000 0000 0000 0000 0101
5右移3位后結果為0,0的二進制為: 0000 0000 0000 0000 0000 0000 0000 0000? ? ? ? // (用0進行補位)
?-5換算成二進制: 1111 1111 1111 1111 1111 1111 1111 1011
-5右移3位后結果為-1,-1的二進制為: 1111 1111 1111 1111 1111 1111 1111 1111 ? // (用1進行補位)
-5無符號右移3位后的結果?536870911 換算成二進制: 0001 1111 1111 1111 1111 1111 1111 1111 ??// (用0進行補位)
通過其結果轉換成二進制后,我們可以發(fā)現,正數右移,高位用0補,負數右移,高位用1補,當負數使用無符號右移時,用0進行部位(自然而然的,就由負數變成了正數了)
注意:筆者在這里說的是右移,高位補位的情況。正數或者負數左移,低位都是用0補。(自行測試)
4、位與(?&?)
public class Test {
public static void main(String[] args) {
System.out.println(5 & 3);//結果為1
}
}
還是老套路,將2個操作數和結果都轉換為二進制進行比較:
5轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0101
3轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0011
-------------------------------------------------------------------------------------
1轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0001
位與:第一個操作數的的第n位于第二個操作數的第n位如果都是1,那么結果的第n為也為1,否則為0
5、位或( |?)
public class Test {
public static void main(String[] args) {
System.out.println(5 | 3);//結果為7
}
}
5轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0101
3轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0011
-------------------------------------------------------------------------------------
7轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0111
位或操作:第一個操作數的的第n位于第二個操作數的第n位 只要有一個是1,那么結果的第n為也為1,否則為0
6、位異或(?^?)
package com.xcy;
public class Test {
public static void main(String[] args) {
System.out.println(5 ^ 3);//結果為6
}
}
5轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0101
3轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0011
-------------------------------------------------------------------------------------
6轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0110
位異或:第一個操作數的的第n位于第二個操作數的第n位 相反,那么結果的第n為也為1,否則為0
7、位非(?~?) ? ? ? ? ??位非是一元操作符
package com.xcy;
public class Test {
public static void main(String[] args) {
System.out.println(~5);//結果為-6
}
}
?5轉換為二進制:0000 0000 0000 0000 0000 0000 0000 0101
-------------------------------------------------------------------------------------
-6轉換為二進制:1111 1111 1111 1111 1111 1111 1111 1010
位非:操作數的第n位為1,那么結果的第n位為0,反之。
由位運算操作符衍生而來的有:
&= 按位與賦值
|=? 按位或賦值
^= 按位非賦值
>>= 右移賦值
>>>= 無符號右移賦值
<<= 賦值左移
和 += 一個概念而已。
舉個例子:
package com.xcy;
public class Test {
public static void main(String[] args) {
int a = 5
a &= 3;
System.out.println(a);//結果是1
}
}
--------------------