2012-03-22 41 views
7

Hi guys: Tôi đã rất ngạc nhiên khi thấy rằng đoạn mã sauJava: Char so với kích thước byte chuỗi.

System.out.println("Character size:"+Character.SIZE/8); 
System.out.println("String size:"+"a".getBytes().length); 

Đầu ra này:

kích thước nhân vật: 2

Chuỗi kích thước: 1

tôi sẽ giả sử rằng một chuỗi ký tự đơn sẽ mất cùng một byte (hoặc nhiều hơn) so với một char đơn.

Trong im đặc biệt tự hỏi ---

Nếu tôi có một đậu java với một số lĩnh vực trong đó, làm thế nào kích thước của nó sẽ tăng lên tùy theo tính chất của các trường (nhân vật, String, Boolean, Vector vv ..) Tôi giả định rằng tất cả các đối tượng java có một số dấu chân (có thể là tối thiểu), và rằng một trong những dấu chân nhỏ nhất này sẽ là một ký tự đơn. Vì vậy .. Để kiểm tra giả thiết cơ bản đó, tôi bắt đầu với đoạn mã trên - và kết quả của các câu lệnh in có vẻ phản trực giác.

Bất kỳ thông tin chi tiết nào về cách lưu trữ java/serializes ký tự và chuỗi theo mặc định sẽ rất hữu ích ... cảm ơn.

+5

Độ dài của chuỗi là số ký tự chứa trong đó. Một ký tự có thể được mã hóa trong nhiều hơn một byte. – Oded

+4

Chuỗi có thể được mã hóa UTF-8, do đó, "a" chỉ mất một byte. –

+4

[Tối thiểu tuyệt đối cho mọi nhà phát triển phần mềm hoàn toàn, tích cực phải biết về bộ ký tự Unicode và ký tự (Không có lý do!)] (Http://www.joelonsoftware.com/articles/Unicode.html) – Oded

Trả lời

10

getBytes() kết quả đầu ra là String với mã hóa mặc định (rất có thể là ISO-8859-1) trong khi char ký tự bên trong luôn là 2 byte. Java nội bộ sử dụng mảng char luôn với một byte 2 byte, nếu bạn muốn biết thêm về mã hóa, hãy đọc liên kết bằng Oded trong các bình luận câu hỏi.

+3

Để tham khảo, 'getBytes()' không thực sự cho bạn biết mức tiêu thụ bộ nhớ thực tế của 'Chuỗi'. –

+0

Tôi không nghĩ rằng tuyên bố này của bạn là chính xác: "Java nội bộ sử dụng luôn mảng char với một char 2 byte." Bạn có thể thấy liên kết này: http://javarevisited.blogspot.com.tr/2012/01/get-set-default-character-encoding.html Đối với tôi, Java đã sử dụng UTF-8 làm mã hóa mặc định trong mã. –

+0

@KorayTugay Bạn có thể trộn lẫn những gì biểu diễn bộ nhớ trong của Unicode trong Java là (có, mọi thực thi CharSequence như String vẫn đang sử dụng 2 ký tự byte theo định dạng UTF-16) và Java nhập hoặc xuất biểu diễn nội bộ (tệp, mạng) trong các mã hóa byte cụ thể. Nếu bạn vẫn tin rằng phiên bản Java của bạn (đó là ...?) Sử dụng nội bộ UTF-8, làm thế nào bạn chứng minh điều đó? Nhân tiện, vấn đề của hàm getBytes() là hàm rất cũ, nó đã có sẵn trong phiên bản 1.1 khi UTF-8 không được hỗ trợ, vì vậy bạn không thể dự đoán rằng nó sử dụng UTF-8. –

-1

SIZE của ký tự là dung lượng cần thiết cho một char, là 16 bit. Độ dài của một chuỗi (cũng là độ dài của mảng char hoặc mảng byte cơ bản) là số ký tự (hoặc byte), không phải là kích thước theo bit.

Đó là lý do tại sao bạn đã thực hiện việc chia cho 8 cho kích thước, nhưng không phải cho độ dài. Độ dài cần được nhân với hai.

Cũng lưu ý rằng bạn sẽ nhận được độ dài khác cho mảng byte nếu bạn chỉ định một mã hóa khác. Trong trường hợp này, việc chuyển đổi sang mã hóa đơn hoặc thay đổi được thực hiện khi thực hiện getBytes().

Xem: http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#getBytes(java.nio.charset.Charset)

+0

Không, anh ta sử dụng 'getBytes()', vì vậy những gì anh ta nhận được thực sự là số byte (cũng không đáng ngạc nhiên). –

+0

Có câu trả lời này là một chút tắt chủ đề và mischaracterizes câu hỏi ... Tôi đề nghị một bản cập nhật. – jayunit100

2

Tôi muốn nói những gì tôi nghĩ, chính xác cho tôi nếu tôi đã sai lầm nhưng bạn đang tìm kiếm theo chiều dài của chuỗi được một cách chính xác nó được hiển thị như 1 như bạn chỉ có 1 nhân vật trong chuỗi. chiều dài cho thấy chiều dài không phải là kích thước. chiều dài và kích thước là hai thứ khác nhau.

séc Link này .. bạn đang tìm kiếm số byte chiếm đóng một cách sai lầm

0

tốt, bạn có mà 1 char trong mảng char có kích thước của 2 byte và rằng chuỗi của bạn chứa là 1 nhân vật dài , không phải là nó có kích thước 1 byte.

Đối tượng String trong Java bao gồm:

private final char value[]; 
private final int offset; 
private final int count; 
private int hash; 

chỉ này nên đảm bảo với bạn rằng anyway các đối tượng String là lớn hơn sau đó char mảng. Nếu bạn muốn tìm hiểu thêm về kích thước của đối tượng, bạn cũng có thể đọc về các tiêu đề đối tượng và yếu tố đa dạng cho mảng char. Ví dụ: here hoặc here.

+0

điều này không có ý nghĩa bạn có thể cố gắng cải thiện ngữ pháp ... v.v. – jayunit100

0

Tôi muốn thêm một số mã đầu tiên và sau đó một chút giải thích:

import java.nio.charset.Charset; 

public class Main { 

    public static void main(String[] args) { 
     System.out.println("Character size: " + Character.SIZE/8); 
     final byte[] bytes = "a".getBytes(Charset.forName("UTF-16")); 
     System.out.println("String size: " + bytes.length); 
     sprintByteAsHex(bytes[0]); 
     sprintByteAsHex(bytes[1]); 
     sprintByteAsHex(bytes[2]); 
     sprintByteAsHex(bytes[3]); 
    } 

    static void sprintByteAsHex(byte b) { 
     System.out.print((Integer.toHexString((b & 0xFF)))); 
    } 
} 

Và kết quả sẽ là:

Character size: 2 
String size: 4 
feff061 

Vì vậy, những gì bạn đang thực sự thiếu là, bạn không cung cấp bất kỳ tham số nào cho phương thức get2yte của phương thức . Có lẽ, bạn đang nhận được các byte cho biểu diễn UTF-8 của ký tự 'a'.

Vâng, nhưng tại sao chúng tôi nhận được 4 byte, khi chúng tôi yêu cầu UTF-16? Ok, Java sử dụng UTF-16 nội bộ, sau đó chúng ta nên nhận được 2 byte phải không?

Nếu bạn kiểm tra kết quả:

feff061 

Java thực sự trở lại cho chúng ta một BOM: https://en.wikipedia.org/wiki/Byte_order_mark.

Vì vậy, 2 byte đầu tiên: feff là bắt buộc để báo hiệu rằng các byte sau sẽ là UTF-16 Big Endian. Vui lòng xem trang Wikipedia để biết thêm thông tin.

2 byte còn lại: 0061 là biểu diễn 2 byte của ký tự "a" bạn có. Có thể được xác minh từ: http://www.fileformat.info/info/unicode/char/0061/index.htm

Vì vậy, có, ký tự trong Java là 2 byte, nhưng khi bạn yêu cầu byte không có mã hóa cụ thể, bạn có thể không nhận được 2 byte vì mã hóa khác nhau sẽ yêu cầu số lượng byte khác nhau nhân vật.

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