2009-12-20 32 views
9

Tôi chuẩn bị bắt đầu làm việc với thứ gì đó đòi hỏi phải đọc byte và tạo chuỗi. Các byte được đọc đại diện cho các chuỗi UTF-16. Vì vậy, chỉ để kiểm tra những điều tôi muốn chuyển đổi một mảng byte đơn giản trong mã hóa UTF-16 thành một chuỗi. 2 byte đầu tiên trong mảng phải đại diện cho endianness và do đó phải là 0xff 0xfe hoặc 0xfe 0xff. Vì vậy, tôi đã thử tạo mảng byte của tôi như sau:Chuyển đổi ngầm ẩn của int thành byte

byte[] bytes = new byte[] {0xff, 0xfe, 0x52, 0x00, 0x6F, 0x00}; 

Nhưng tôi gặp lỗi vì 0xFF và 0xFE quá lớn để vừa với byte (vì byte được ký bằng Java). Chính xác hơn lỗi là int không thể được chuyển đổi thành một byte. Tôi biết rằng tôi chỉ có thể chuyển đổi một cách rõ ràng từ int sang byte với một dàn diễn viên và đạt được kết quả mong muốn, nhưng đó không phải là câu hỏi của tôi.

Chỉ cần thử một cái gì đó ra tôi tạo ra một String và được gọi là getBytes ("UTF-16") sau đó in mỗi byte trong mảng. Đầu ra hơi khó hiểu vì hai byte đầu tiên là 0xFFFFFFFE 0xFFFFFFFF, theo sau là 0x00 0x52 0x00 0x6F. (Obvisouly endianness ở đây là khác nhau từ những gì tôi đã cố gắng để tạo ra ở trên nhưng đó không phải là quan trọng).

Sử dụng đầu ra này, tôi quyết định thử và tạo ra mảng byte của tôi cùng một cách:

byte[] bytes = new byte[] {0xffffffff, 0xfffffffe, 0x52, 0x00, 0x6F, 0x00}; 

Điều lạ lùng là nó làm việc tốt. Vì vậy, câu hỏi của tôi là, tại sao Java cho phép một giá trị số nguyên của 0xFFFFFF80 hoặc cao hơn để được tự động chuyển đổi sang một byte mà không có một diễn viên rõ ràng, nhưng bất cứ điều gì bằng hoặc lớn hơn 0x80 yêu cầu một diễn viên rõ ràng?

Trả lời

10

Điều quan trọng cần nhớ ở đây là int trong Java là một giá trị đã ký. Khi bạn chỉ định 0xffffffff (là 2^32 -1), số này được dịch thành một giá trị có chữ ký -1 - một số int thực sự không thể đại diện cho thứ gì đó lớn như 0xffffffff làm số dương.

Vì vậy, đối với các giá trị nhỏ hơn 0x80 và lớn hơn 0xFFFFFF80, kết quả là giá trị int nằm trong khoảng từ -128 đến 127, có thể được biểu thị rõ ràng là byte. Bất kỳ thứ gì ngoài phạm vi đó đều không thể, và cần ép buộc với một diễn viên rõ ràng, mất dữ liệu trong tiến trình.

+0

Cảm ơn, điều đó làm cho nó rõ ràng hơn nhiều. – DaveJohnston

2

Nếu bạn sử dụng một số không có gợi ý (ví dụ: 1234L trong một thời gian dài) trình biên dịch sẽ giả định một số nguyên. Giá trị 0xffffffff là một số nguyên có giá trị -1 có thể được truyền tới byte mà không có cảnh báo.

+1

... vì Java sử dụng ký hiệu bổ sung của hai cho giá trị âm. – Ash

0

Vì 0xffffffff là số -1 và -1 có thể được hiểu là byte.

0

0xff cũng giống như viết 0x000000ff, không phải 0xffffffff. Vì vậy, đó là vấn đề của bạn; số nguyên là một số dương (255), nhưng byte (nếu bit-bit được chuyển đổi) sẽ là một số âm (-1). Nhưng 0xffffffff là -1 cả hai dạng là int và dưới dạng byte.

0

Vì int được ký và 0xffffffff đại diện -1 và 0xff đại diện cho một số nguyên có giá trị 255, không nằm trong phạm vi -128 (0x80) +127 (0x7f) của byte.

Các vấn đề liên quan