222

In Java, if I have a String x, how can I calculate the number of bytes in that string?

5
  • 20
    One might want to use a String to represent the body of an HTTP response and use the size to set the "Content-Length" header, which is specified in octets/bytes not characters. w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.13 Commented Dec 18, 2012 at 20:58
  • 4
    A database column may have length restriction in bytes, e.g. VARCHAR2 (4000 BYTE) in Oracle. One might want to know the byte count of a String in desired encoding to know if the String would fit. Commented Jun 4, 2013 at 6:09
  • @iX3 Exactly the same as I was trying to do. Commented Jun 28, 2013 at 10:47
  • 1
    I believe there are two possible interpretations of this question, depending on the intent: One is "how much memory does my String use?". The answer to that is provided by @roozbeh below (maybe modulo VM subtleties like compressed OOPS). The other is, "if I convert the string to a byte[] how much memory would that byte array use?". This is the question that is answered by Andrzej Doyle. The difference can be large: "Hello World" in UTF8 is 11 bytes, but the String (per @roozbeh) is 50 bytes (if my math is right). Commented Jun 19, 2016 at 13:13
  • I should have added that the 11 bytes doesn't include the overhead of the byte[] object that holds them, so the comparison is somewhat misleading. Commented Jun 19, 2016 at 13:27

10 Answers 10

345

A string is a list of characters (i.e. code points). The number of bytes taken to represent the string depends entirely on which encoding you use to turn it into bytes.

That said, you can turn the string into a byte array and then look at its size as follows:

// The input string for this test
final String string = "Hello World";

// Check length, in characters
System.out.println(string.length()); // prints "11"

// Check encoded sizes
final byte[] utf8Bytes = string.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "11"

final byte[] utf16Bytes= string.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "24"

final byte[] utf32Bytes = string.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "44"

final byte[] isoBytes = string.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "11"

final byte[] winBytes = string.getBytes("CP1252");
System.out.println(winBytes.length); // prints "11"

So you see, even a simple "ASCII" string can have different number of bytes in its representation, depending which encoding is used. Use whichever character set you're interested in for your case, as the argument to getBytes(). And don't fall into the trap of assuming that UTF-8 represents every character as a single byte, as that's not true either:

final String interesting = "\uF93D\uF936\uF949\uF942"; // Chinese ideograms

// Check length, in characters
System.out.println(interesting.length()); // prints "4"

// Check encoded sizes
final byte[] utf8Bytes = interesting.getBytes("UTF-8");
System.out.println(utf8Bytes.length); // prints "12"

final byte[] utf16Bytes= interesting.getBytes("UTF-16");
System.out.println(utf16Bytes.length); // prints "10"

final byte[] utf32Bytes = interesting.getBytes("UTF-32");
System.out.println(utf32Bytes.length); // prints "16"

final byte[] isoBytes = interesting.getBytes("ISO-8859-1");
System.out.println(isoBytes.length); // prints "4" (probably encoded "????")

final byte[] winBytes = interesting.getBytes("CP1252");
System.out.println(winBytes.length); // prints "4" (probably encoded "????")

(Note that if you don't provide a character set argument, the platform's default character set is used. This might be useful in some contexts, but in general you should avoid depending on defaults, and always use an explicit character set when encoding/decoding is required.)

Sign up to request clarification or add additional context in comments.

13 Comments

so again if i use getBytes().it will give me the length same as x.length am i wrong because i am not sure
@Green Ash The length of the byte array -- getBytes() -- and x.length MAY be equal but is not guaranteed to be so. It will be equal if all the characters are represented by a single byte each. This will always hold true for character encodings that use a single byte per character (or less), such as ISO-8859-1. UTF-8 uses either 1 or 2 bytes, so it depends on the exact characters in the string. Then there are character encodings that always use two bytes per character.
i like your answer :) , so they might in somehow be the same but not always am i right? o.k. then is it ok to use the method without the parameter because it causing to me an error!!
@Green the point is that number of bytes is not always the same as the number of characters. The number of bytes depends on the character encoding that's used. You'll have to know which character encoding you're going to use and take that into account. What error are you getting? If you just use getBytes() it will use the default character encoding of your system.
@KorayTugay Yes, more or less. You could argue about the order of cause and effect, though. I'd be more inclined to state that a char is always 2 bytes because it is a primitive data type defined to be 2 bytes wide. (And that the UTF-16 representation was mainly a consequence of this, rather than the other way round.)
|
70

If you're running with 64-bit references:

sizeof(string) = 
8 + // object header used by the VM
8 + // 64-bit reference to char array (value)
8 + string.length() * 2 + // character array itself (object header + 16-bit chars)
4 + // offset integer
4 + // count integer
4 + // cached hash code

In other words:

sizeof(string) = 36 + string.length() * 2

On a 32-bit VM or a 64-bit VM with compressed OOPs (-XX:+UseCompressedOops), the references are 4 bytes. So the total would be:

sizeof(string) = 32 + string.length() * 2

This does not take into account the references to the string object.

3 Comments

I was assuming the question was about the number of bytes allocated in memory for a String object. If the question is about the number of bytes required to serialize the String, as others have pointed out, it depends on the encoding used.
Source for ur answer ? Thanks
Note: sizeof should be multiple of 8.
26

The pedantic answer (though not necessarily the most useful one, depending on what you want to do with the result) is:

string.length() * 2

Java strings are physically stored in UTF-16BE encoding, which uses 2 bytes per code unit, and String.length() measures the length in UTF-16 code units, so this is equivalent to:

final byte[] utf16Bytes= string.getBytes("UTF-16BE");
System.out.println(utf16Bytes.length);

And this will tell you the size of the internal char array, in bytes.

Note: "UTF-16" will give a different result from "UTF-16BE" as the former encoding will insert a BOM, adding 2 bytes to the length of the array.

3 Comments

Roozbeh's answer is better, because it takes the other bytes into account as well.
@finnw Are you sure that the encoding is UTF-16BE and not UTF-16? According to the String class Javadoc (docs.oracle.com/javase/6/docs/api/java/lang/String.html), "A String represents a string in the UTF-16 format...".
No longer true since Java 9, openjdk.org/jeps/254, where ASCII-only Strings are now internally encoded as a byte[] with a single byte per character.
19

According to How to convert Strings to and from UTF8 byte arrays in Java:

String s = "some text here";
byte[] b = s.getBytes("UTF-8");
System.out.println(b.length);

5 Comments

but excuse me when i compile your code it gives me an error ; because of the parameter "UTF-8".where when i pass an empty parameter it gives me the length same as x.length . i misunderstand the concept. help please
@Green Ash, what version of Java do you have?
@Green Ash, what exception are you getting?
to be clear this is the output: test.java:11: unreported exception java.io.UnsupportedEncodingException; must be caught or declared to be thrown byte[] b = s.getBytes("UTF-8"); ^ 1 error Process completed.
@Green, try: s.getBytes(Charset.forName("UTF-8")).
10

A String instance allocates a certain amount of bytes in memory. Maybe you're looking at something like sizeof("Hello World") which would return the number of bytes allocated by the datastructure itself?

In Java, there's usually no need for a sizeof function, because we never allocate memory to store a data structure. We can have a look at the String.java file for a rough estimation, and we see some 'int', some references and a char[]. The Java language specification defines, that a char ranges from 0 to 65535, so two bytes are sufficient to keep a single char in memory. But a JVM does not have to store one char in 2 bytes, it only has to guarantee, that the implementation of char can hold values of the defines range.

So sizeof really does not make any sense in Java. But, assuming that we have a large String and one char allocates two bytes, then the memory footprint of a String object is at least 2 * str.length() in bytes.

Comments

8

There's a method called getBytes(). Use it wisely .

4 Comments

Wisely = don't use the one without a character set parameter.
Why? Is this an issue if i configure my environment to run with UTF8 encoding?
getBytes will also create and copy the array of bytes, so if you're talking long strings, this operation could get pricey.
@ticktock, if you're still around, yes but what is the alternative? I got here hoping for a library function to return the storage needed so I can combine it into a larger allocation.
4

Try this :

Bytes.toBytes(x).length

Assuming you declared and initialized x before

1 Comment

Is this part of the standard Java library? I can't find the Bytes class.
3

To avoid try catch, use:

String s = "some text here";
byte[] b = s.getBytes(StandardCharsets.UTF_8);
System.out.println(b.length);

Comments

3

Try this using apache commons:

String src = "Hello"; //This will work with any serialisable object
System.out.println(
            "Object Size:" + SerializationUtils.serialize((Serializable) src).length)

Comments

0

If you want to reference Charset from some standard package instead of using String literal "UTF-8" then you can use java.nio

import java.nio.charset.StandardCharsets;
..
int numBytes = myString.getBytes(StandardCharsets.UTF_8).length;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.