在瞭解數據類型轉換之前,先回憶,java的基本的數據類型,有8種,除了布爾之外,其餘的7種經常遇到不同類型的轉換問題!
還有就是布爾型的,java規範強烈的不建議布爾型和整型或者浮點型的進行轉化,很容易出錯,也沒必要!
int big = 123456789;//億級別的大數字
float Big = big;
System.out.println(big);
System.out.println(Big);
丟失了精度,打印結果;123456789
1.23456792E8
byte b = 0;//就是一個字節的空間
byte a = 10;//10也是一個字節的空間
System.out.println(a);
System.out.println(b);
byte c = 100;//8位二進制
System.out.println(c);
byte d = 127;
System.out.println(d);
//byte e = 128;
byte f = -128;
//byte g = -129;
如果把註釋拿掉,編譯就會報錯!已經超出了byte的存儲範圍!(-128到127),總之就是同樣的類型(比如都是整型),則存儲空間小的可以向大的轉化,反之不行,對於存儲空間一樣的不同類型,也儘量不轉化,比如double和long,int和float,不同類型下,存儲空間小的可以向大的轉化,比如int到double。
byte b = 10;
int iA = 123456789;
//byte轉爲int,精度永遠不丟失
int i = b;
System.out.println(i);//10
//byte轉爲更高的更是如此
long l = b;
System.out.println(l);//10
再看一個精細的實驗;
public class lab2 {
public static void main(String[] args) {
// byte類型沒有後綴標識,默認就是和int型一樣
byte byteNum = 1;
// 賦值long型,對不起,編譯都出錯了
// byte byteU = 9l;
// 同理,short類型也不用後綴,編譯器自動檢測範圍
short shortNum = 1111;
// 同理,賦值long,報錯
// shortNum = 1l;
// int的也是默認沒有後綴
int intNum = 3413;
// 同理,即使不超出範圍,賦值long也不行!!!!!!
// int intN = 1231L;
// 給long賦值,int範圍內的寫L和不寫L都行
long longNum = 1234;
// 但是超出int的數值,必須加L才能編譯過去
long longN = 12345678902L;
// 針對浮點型
float floatNum = 111;
// 比如,int賦值給float,編譯雖然能通過,但是代碼多了很容易出錯,丟失精度!
float float_a = 12341;
// 記住,不到萬不得已,不要隨便這樣用,習慣不好,思維體現的是不嚴謹性。
int iA = 12345155;
float floatInt = iA;
System.out.println(floatInt);// 1.2345155E7 ok!
int iB = 1411412413;
floatInt = iB;
System.out.println(floatInt);// 1.41141235E9 flase!
// 同理,long型直接賦值給float也是可以的,但是不嚴謹
float float_long = 1231L;
float float_b = 1231451111;
System.out.println(float_b);// 1.23145114E9 flase!
// 這樣是不行的,沒有後綴d的默認爲double,不能編譯通過
// float float_c = 13.521;
// float類型的浮點數,必須加後綴f區分!!!
float f = 111.1f;
// 同樣,不能把double賦值給float,編譯出錯,和long賦值給int出錯一個道理
// f = 123D;
// double類型的沒有後綴,那麼默認就是double
double doubleNum = 1.4124;
// int類型可以賦值給double類型
doubleNum = 12313;
// long型可以直接賦值給double,但是同樣注意精度問題!!!!!
doubleNum = 123123L;
// float類型可以直接賦值給double
doubleNum = 21.13F;
// 把大的賦值給小的(大小說的是存儲空間佔據的字節數),編譯出錯
// 比如double賦值給byte,編譯出錯
// byteNum = 1.31D;
// double賦值short類型,編譯報錯,即使這個值沒有超出short類型的取值範圍 。
// short shortNum = 1.0D;
// double賦值int,編譯時報錯,都是同理。
// int intAB = 1.0D;
// double賦值給一個long變量,編譯報錯!!!!倒過來可以的,但是有時會發生精度損失。
// long longAB = 1.0D;
// char類型,必須是單個字符賦值
char charA = 'a';
// 這樣的串兒不行
// char a = "412d"
// char a = '21';
// 可以把int的賦值給char,當然必須是範圍內的,不過不建議這樣亂用。(反過來當然更可以了!!!)
char chaB = 1231;
// 但是把long,float,double的賦值給char就編譯出錯!即使沒有超過範圍!
// chaB = 134144l;
// charA = 12.12F;
}
}
總的來說,就是小的轉大的,儘量避免大的轉小的。
JAVA中的數值類型不存在無符號數,它們的取值範圍是固定的,不會隨着機器硬件環境或者操作系統的改變而改變。實際上,JAVA中還存在另外一種基本類型void,它也有對應的包裝類 java.lang.Void,不過我們無法直接對它們進行操作。對於數值類型的基本類型的取值範圍,我們無需強制去記憶,因爲它們的值都已經以常量的形式定義在對應的包裝類中了。
public class lab1 {
public static void main(String[] args) {
// java的基本數據類型
// 類型的位數
System.out.println(Byte.SIZE);// 8
// 最大值
System.out.println(Byte.MAX_VALUE);// 127
// 最小值
System.out.println(Byte.MIN_VALUE);// -128
// short類型
System.out.println(Short.SIZE);// 16
System.out.println(Short.MAX_VALUE);// 32767
System.out.println(Short.MIN_VALUE);// -32768
// int類型
System.out.println(Integer.SIZE);// 32
System.out.println(Integer.MAX_VALUE);// 2147483647
System.out.println(Integer.MIN_VALUE);// -2147483648
// long int類型
System.out.println(Long.SIZE);// 64
System.out.println(Long.MAX_VALUE);// 9223372036854775807
System.out.println(Long.MIN_VALUE);// -9223372036854775808
// double類型
System.out.println(Double.SIZE);// 64
System.out.println(Double.MAX_VALUE);// 1.7976931348623157E308
System.out.println(Double.MIN_VALUE);// 4.9E-324
// float 類型
System.out.println(Float.SIZE);// 32
System.out.println(Float.MAX_VALUE);// 3.4028235E38
System.out.println(Float.MIN_VALUE);// 1.4E-45
// char類型
System.out.println(Character.SIZE);// 16
System.out.println((int) Character.MAX_VALUE);// 65535
System.out.println((int) Character.MIN_VALUE);// 0
}
}
浮點數是以科學記數法的形式輸出的,結尾的“E+數字”表示E之前的數字要乘以10的多少倍(-就代表是除以10的多少倍)。
比如;1.1E2意思是說,1.1x100=110
再看,如果二元操作符的兩邊的變量類型不一致,那麼一定是先類型提升爲同一個類型!再計算!有如下規律;
未帶有字符後綴標識的整數默認爲int類型;未帶有字符後綴標識的浮點數默認爲double類型。
// 定義一個短整型數據
short shortNum = 12314;
// 兩個參數中,一個是int,一個short int則自動類型提升錯誤!提升的結果爲int型,它不能賦值給short類型
// shortNum = shortNum + 12;
// 沒問題,不需要類型提升,並且沒有超出範圍
shortNum = 31 + 214;
//針對+=符合賦值符號,java的編譯器有特殊處理,不會報錯!!!!!這是需要注意的!
shortNum += 1;
對於一個是浮點數(float或者double),一個是整型(int,short,long,byte),那麼有如下的規律
1、如果一個是double類型,則另一個提升爲double
2、否則的話,如果一個是float類型,則另一個提升爲float.
3、否則,如果一個是long類型,那麼另一個提升爲long類型
4、否則,兩個參數都被提升爲int型
=======================================================================================================================
小結;
1、如果一個整數的值超出了int類型能夠表示的範圍,則必須增加後綴“L”(建議用大寫,防止混淆),表示爲long型。
2、帶有“F”後綴的整數和浮點數都是float類型的;
3、帶有“D”後綴的整數和浮點數都是double類型的。
4、編譯器會在編譯期對byte、short、int、long、float、double、char型變量的值進行檢查,如果超出了它們的取值範圍就會報錯。
5、int型值理論上是可以賦給所有數值類型的變量的,long型值理論上可以賦給long、float、double類型的變量,但是注意精度的丟失!!!!!!
6、float型值可以賦給float、double類型的變量,double型值只能賦給double類型變量!!!!
7、只要兩個操作數中有一個是double類型的,另一個將會被轉換成double類型,並且結果也是double類型,否則,只要兩個操作數中有一個是float類型的,另一個將會被轉換成float類型,並且結果也是float類型;否則,只要兩個操作數中有一個是long類型的,另一個將會被轉換成long類型,並且結果也是long類型;否則,兩個操作數(包括byte、short、int、char)都將會被轉換成int類型,並且結果也是int類型。
當使用+=、-=、*=、/=、%=、運算符對基本類型進行運算時,遵循如下規則:
運算符右邊的數值將首先被強制轉換成與運算符左邊數值相同的類型,然後再執行運算,且運算結果與運算符左邊數值類型相同。
========================================================================================================================
當然,還有一招,那就是強制類型的轉化!
如果,程序裏一定要把double轉化爲int!那麼可以這樣;
int i = 12312;
double d = 1.31;
i = (int)d;
編譯通過,沒問題!打印i的值;結果是1,因爲強制類型轉化之後,小數點後面的被截斷,d成了整型了!
如果在實際程序中,想把一個小數,四捨五入怎麼辦?那麼可以使用Math.round方法。round單詞本身具有四捨五入的含義。
double double_round = 1.1111124;
System.out.println(Math.round(double_round));
打印1
注意;
1、如果在四捨五入操作之後,想去賦值給整型,那麼還是需要進行強制類型轉換!因爲
long java.lang.Math.round(double a)
Returns the closest long
to the argument, with ties rounding up
返回的是long類型,賦給int型,有可能產生精度丟失的問題,不確定!故編譯報錯!比如;
long longNUM = Math.round(double_round);.
就不用強制類型轉化。完全符合規範。
2、如果強制類型轉換的時候,超出了目標類型的範圍,那麼截斷的時候,就有可能得到另外一個完全不同的值。