Java中的byte[]/char[]/int/String資料型別轉換
你也可以檢視我的其他同類文章,也會讓你有一定的收貨!
常用的編碼方式有Unicode、ASCII、UTF-8、GB2312、ISO-8899-1等。採用不同的編碼方式,同樣的n位二進位制“數字”組合代表的“字元”也會不一樣。具體採用什麼樣的編碼方式,對“字元”怎樣解析,就要看程式設計所在的平臺是什麼樣了。同時,為了方便,我們並不會直接用n位二進位制的表示,而是用它的十六進位制表示。
八種基本資料型別:
資料型別 | 名稱 | 長度 | 備註 |
---|---|---|---|
byte | 位元組型 | 1位元組 = 8bit | 表示資料範圍:-128~127 |
short | 短整型 | 2位元組 = 16bit | |
char | 字元型 | 2位元組 = 16bit | 等價於Unicode編碼 |
int | 整型 | 4位元組 = 32bit | |
long | 長整型 | 8位元組 | |
float | 單精度浮點型 | 4位元組 | 精度:7-8位 |
double | 雙精度浮點型 | 8位元組 | |
boolean | 布林型 | true/false |
各資料之間轉化:
1.String<—>byte[]
1.1 String—>byte[]
byte[] bytes = mString.getBytes();
String預設使用utf-8編碼,將mString中的二進位制(使用utf-8編碼後的二進位制),每個位元組儲存在bytes中。
例如: mString中的 值:’タ’ 65408 被轉為 bytes 中的 -17, -66 ,-128
65408 對應二進位制 1111 1111 1000 0000,這個資料使用utf-8編碼後的二進位制為:1110 1111 1011 1110 1000 0000,對應- 17,-66, -128
關於編碼,可以檢視我的這篇部落格
1.2 byte[]—>String
//1、預設使用utf-8編碼
String String1 = new String(bytes );
//2、指定其他編碼方式
String String2 = new String(bytes, StandardCharsets.US_ASCII);
String String21 = new String(bytes, StandardCharsets.ISO_8859_1);
- 可以指定byte[]—>String使用的編碼型別
- String一個字元是16bit,轉化時對byte (8bit)進行符號擴充套件
- 使用預設的utf-8編碼時,如果byte的二進位制資料不符合utf-8編碼規範,則轉化後 String對應的字元為’�’ 65533
2.String<—>char[]
2.1、String—>char[]
String s = "SSSSSSS";
char[] ss = s.toCharArray();
2.2、char[]—>String
char[] chars4 = {0x0001, 0xfff0, 0xf0, 'a', 0x4E25};
String string4 = new String(chars4);
- char也是使用utf-8編碼,如果char的二進位制資料不符合utf-8編碼規範,使用者看到的字元為空。
- 因為char已經是字元,所以直接把字元賦給String 。
3.String<—>int
3.1、String—>int
String string9 = "嚴";
int i9 = Integer.parseInt(string9);
Exception in thread “main” java.lang.NumberFormatException: For input string: “嚴”
如果String 不是資料,會丟擲異常
3.2、int—>String
int i = 10;
//轉化
String string9 = String.valueOf(i);
//2、直接使用字串加上i,java會自動轉化
string9 = "" + i;
4.String<—>char
4.1、String—>char
String string = "嚴";
char char = string.charAt(0);
4.2、char—>String
char char1 = a;
//轉化
String string9 = String.valueOf(char1);
//2、直接使用字串加上i,java會自動轉化
string9 = "" + char1;
5.String<—>byte
5.1、String—>byte
可以先轉為String—>byte[],在取出其中的byte
5.1、byte—>String
byte byte1 = 0xff;
//轉化
String string9 = String.valueOf(byte1);
//2、直接使用字串加上i,java會自動轉化,string9 內容為 -1
string9 = "" + byte1;
注意:byte是未經過編碼的二進位制資料,所以在直接轉為String 時,使用者看到的是二進位制對應的十進位制數值
6.int<—>char<—>byte
public static void main(String[] args) {
byte b=-1;
System.out.println((int)(char)b);
System.out.println((int)(char)(b & 0xff));
}
執行結果是:65535和255
如果你對輸出結果感到很驚訝,請繼續往下讀…
1、 int(32位) -> byte(8位)
-1是int型的字面量,根據“2的補碼”編碼規則,編碼結果為0xffffffff,即32位全部置1.轉換成byte型別時,直接擷取最後8位,所以byte結果為0xff,對應的十進位制值是-1.
2、 byte(8位) -> char(16位)
由於byte是有符號型別,所以在轉換成char型(16位)時需要進行符號擴充套件,即在0xff左邊連續補上8個1(1是0xff的符號位),結果是0xffff。由於char是無符號型別,所以0xffff表示的十進位制數是65535。
3、 char(16位) -> int(32位)
由於char是無符號型別,轉換成int型時進行零擴充套件,即在0xffff左邊連續補上16個0,結果是0x0000ffff,對應的十進位制數是65535。
4、 int(32位) -> char(16位)
char c = (char)(b & 0xff);
(b & 0xff)的結果是32位的int型別,前24被強制置0,後8位保持不變,然後轉換成char型時,直接擷取後16位。最後結果為0x00ff
5、 char 與 int 進行運算
int i = c & 0xffff;
0xffff是int型字面量,所以在進行&操作之前,編譯器會自動將c轉型成int型,即在c的二進位制編碼前新增16個0,然後再和0xffff進行&操作,所表達的意圖是強制將前16置0,後16位保持不變。雖然這個操作不是必須的,但是明確表達了不進行符號擴充套件的意圖。
如果需要符號擴充套件,則可以如下編碼:
int i = (short)c; //Cast causes sign extension
首先將c轉換成short型別,它和char是 等寬度的,並且是有符號型別,再將short型別轉換成int型別時,會自動進行符號擴充套件,即如果short為負數,則在左邊補上16個1,否則補上16個0.
Java中資料轉化的一些規則:
- 如果二進位制不符合utf-8的規則,在String 中就會被賦值為65533(對應的二進位制)
- byte是未經編碼的二進位制資料,在java中可以對byte來進行各種編碼。
- 在基本資料型別中,儲存的都是二進位制資料,只是在顯示的時候顯示各自不同的型別。例如:char儲存的二進位制資料顯示出來是使用編碼utf-8後的符號,其它基本資料型別顯示出來都是數字。
基本資料型別轉String,方式多樣化,
- 直接相加,
- String.valueOf()
byte、int、short之間不會互相轉換,因為容量小的資料型別會自動轉換為大的資料型別,所以在運算時,它們都會被轉換為int型
- 容量大的資料型別轉換成容量小的資料型別時,要加上強制轉換符,但可能會造成精度降低或資料溢位
- String不屬於Java的基本資料型別,String的本質是字元陣列,是類物件
我在進行測試時的程式碼:
public class MyClass {
public static void main(String[] args) {
//byte---> string
//byte是未經過編碼的原始資料,轉為string時可以選擇編碼格式
byte[] bytes = {0x1f, (byte) 0x7f, (byte) 0xdf80, (byte) 0x80};
// byte[] packetHeard = {(byte)'\u0080',(byte)'\u0001',(byte)'\u007f',(byte)'\u00ff',(byte)'\u00BA',(byte)'\u00CF'};
//1、預設使用utf-8編碼
String String1 = new String(bytes);
//2、指定其他編碼方式
String String2 = new String(bytes, StandardCharsets.US_ASCII);
String String21 = new String(bytes, StandardCharsets.ISO_8859_1);
//3、使用指定的編碼,把bytes轉為 charBuffer
Charset charSet = Charset.forName("Unicode");
ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length);
byteBuffer.put(bytes);
byteBuffer.flip();
CharBuffer charBuffer = charSet.decode(byteBuffer);
//4、直接使用tostring(),並不能轉為字串
String String3 = bytes.toString();
int i = bytes.hashCode();
String string31 = Integer.toHexString(i);
//5、使用char[] 初始化string,char(顯示是utf-8),所以這裡直接使用了這些字元
//char、int、short等基本型別的資料,都可以直接用二進位制賦值,只是在顯示的時候顯示各自不同的。例如char顯示的是使用編碼utf-8後的符號
//而把這些資料型別轉化為string時,是根據他們顯示的形式加入的stirng
char[] chars4 = {0x0001, 0xfff0, 0x80, 'a', 0x4E25};
short short4 = (short) 0xfff0;
String string4 = new String(chars4);
string4 = String.valueOf(short4);
//6、string 相加,都會保留原來資料屬性(數字就是數字,字元就是字元),可以試著把(char)變為(int)等
String string5 = "";
for (i = 0; i < bytes.length; i++) {
string5 += (char) bytes[i];
}
//string-->byte
//7、預設utf-8編碼,將string5中的二進位制(使用utf-8編碼後的二進位制),每個位元組儲存在bytes6中
byte[] bytes6 = string5.getBytes();
//這個所得結果暫時搞不懂
charSet = Charset.forName("ASCII");
bytes6 = string4.getBytes(charSet);
byte[] b = new byte[2];
b[0] = (byte) ((chars4[4] & 0xFF00) >> 8);
b[1] = (byte) (chars4[4] & 0xFF);
//8、
byte b8 = -1;
System.out.println((int) (char) b8);
System.out.println((int) (char) (b8 & 0xff));
//9
String string9 = "嚴";
int i9 = 0xFFFFFFFF;
string9 = string5 + i9;
char char9 = string9.charAt(0);
}
}
參考: