Considering the String class' length method returns an int, the maximum length that would be returned by the method would be Integer.MAX_VALUE, which is 2^31 - 1 (or approximately 2 billion.)
In terms of lengths and indexing of arrays, (such as char[], which is probably the way the internal data representation is implemented for Strings), Chapter 10: Arrays of The Java Language Specification, Java SE 7 Edition says the following:
The variables contained in an array have no names; instead they are referenced by array access expressions that use nonnegative integer index values. These variables are called the components of the array. If an array has
ncomponents, we saynis the length of the array; the components of the array are referenced using integer indices from0ton - 1, inclusive.
Furthermore, the indexing must be by int values, as mentioned in Section 10.4:
Arrays must be indexed by
intvalues;
Therefore, it appears that the limit is indeed 2^31 - 1, as that is the maximum value for a nonnegative int value.
However, there probably are going to be other limitations, such as the maximum allocatable size for an array.
Answer from coobird on Stack OverflowConsidering the String class' length method returns an int, the maximum length that would be returned by the method would be Integer.MAX_VALUE, which is 2^31 - 1 (or approximately 2 billion.)
In terms of lengths and indexing of arrays, (such as char[], which is probably the way the internal data representation is implemented for Strings), Chapter 10: Arrays of The Java Language Specification, Java SE 7 Edition says the following:
The variables contained in an array have no names; instead they are referenced by array access expressions that use nonnegative integer index values. These variables are called the components of the array. If an array has
ncomponents, we saynis the length of the array; the components of the array are referenced using integer indices from0ton - 1, inclusive.
Furthermore, the indexing must be by int values, as mentioned in Section 10.4:
Arrays must be indexed by
intvalues;
Therefore, it appears that the limit is indeed 2^31 - 1, as that is the maximum value for a nonnegative int value.
However, there probably are going to be other limitations, such as the maximum allocatable size for an array.
java.io.DataInput.readUTF() and java.io.DataOutput.writeUTF(String) say that a String object is represented by two bytes of length information and the modified UTF-8 representation of every character in the string. This concludes that the length of String is limited by the number of bytes of the modified UTF-8 representation of the string when used with DataInput and DataOutput.
In addition, The specification of CONSTANT_Utf8_info found in the Java virtual machine specification defines the structure as follows.
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
You can find that the size of 'length' is two bytes.
That the return type of a certain method (e.g. String.length()) is int does not always mean that its allowed maximum value is Integer.MAX_VALUE. Instead, in most cases, int is chosen just for performance reasons. The Java language specification says that integers whose size is smaller than that of int are converted to int before calculation (if my memory serves me correctly) and it is one reason to choose int when there is no special reason.
The maximum length at compilation time is at most 65536. Note again that the length is the number of bytes of the modified UTF-8 representation, not the number of characters in a String object.
String objects may be able to have much more characters at runtime. However, if you want to use String objects with DataInput and DataOutput interfaces, it is better to avoid using too long String objects. I found this limitation when I implemented Objective-C equivalents of DataInput.readUTF() and DataOutput.writeUTF(String).
Max length of a String?
How to put a max character length on a string
Maximum length of a String in Java - Stack Overflow
How many characters can a Java String have? - Stack Overflow
Videos
Im doing a college assignment and cannot figure how to put a max character length of 40 on a String
You cannot limit the number of characters in a String.
I think,
in your usecase,
the best solution would be to trim the string to the maximum size.
For Example:
String input = "123456789";
String result = input.substring(0, 4);
//result is: "1234"
To ensure that you do not receive an IndexOutOfBoundsException when the input string
is less than the expected length do the following instead:
input.substring(0, Math.min(MAX_CHAR, input.length()));
Math.min() will return the minimum of the two parameters.
When reading data from a file, it would make sense to read your data as a byte[], which obviously has a fixed size.
Converting a byte[] to a String is as easy as new String(bytes, StandardCharsets.UTF8) or any other encoding.
That being said, you could make the encoding configurable in your application, or use the system-default. In that case, you can just new String(bytes) to convert them.
You should be aware though that the size of a String does not always match its size in bytes. In fact for a simple encoding such as US_ASCII or ISO_8859_1 (=Latin1) it's just 1 byte per character. However, an encoding like UTF-8 supports more characters, and will sometimes need multiple bytes to store a single character.
That challenge of encodings and their variable character-size has been around for ages and is the reason why databases have a variety of different datatypes for strings (e.g. VARCHAR vs NVARCHAR).
You should be able to get a String of length
Integer.MAX_VALUEalways 2,147,483,647 (231 - 1)
(Defined by the Java specification, the maximum size of an array, which the String class uses for internal storage)
ORHalf your maximum heap size(since each character is two bytes) whichever is smaller.
I believe they can be up to 2^31-1 characters, as they are held by an internal array, and arrays are indexed by integers in Java.
Not taking the comma and the ellipses into account when calculating the resulting string length and instead setting the max length to 250 is an ugly hack. The code is also a bit buggy, because if the first error message happens to be 250 characters long, you only get ellipses in the result even though there would have been room for the error message, a comma and ellipses.
You should create a method for calculating the result length if a string was appended.
private int calculateResultingLength(String str) {
int result = stringBuilder.length();
if (result > 0) {
result += 1; // Account for a comma.
}
if (errorsDropped) {
result += ELLIPSES.length();
}
result += str.length();
return result;
}
The second isFull check in checkAndAppend is redundant because you already do that check in the append method and checkAndAppend is private. The isFull is now also misleading, because it tells that an error was dropped. The next error might be shorter and fit into the string. I rename it to errorsDropped.
public void append(String str) {
if (calculateResultingLength(str) >= MAX_CAP) {
errorsDropped = true;
} else {
performAppend(str);
}
}
The isFirst field is redundant. You know the append is the first one if the stringBuilder is empty:
private void performAppend(String str) {
if (stringBuilder.length() > 0) {
stringBuilder.append(",");
}
stringBuilder.append(str);
}
The performAppend method became a bit pointless now. You could just write:
public void append(String str) {
if (calculateResultingLength(str) >= MAX_CAP) {
errorsDropped = true;
return;
}
if (stringBuilder.length() > 0) {
stringBuilder.append(",");
}
stringBuilder.append(str);
}
The MAX_CAP and ELLIPSES are named as if they were constants but they are variables. They should be static and final. Also, no need to abbreviate here.
private static final int MAX_CAPACITY = 255;
private static final String ELLIPSES = "...";
Test naming
Consider dropping 'test' from the front of your test names and using the extra space to add something describing the expected outcome for the test, maybe something like...
append_overflowMaxLength_maxLengthNotExceeded
append_withinBuffer_addsMessage
append_overflowMaxLength_entireExceptionReplacedWithElipses
assertEquals
You're passing your parameters to assertEquals the wrong way round (your expected is your actual). Frameworks like assertJ can make assertions more intuitive.
assertThat(result).isEqualTo("...");
assertThat(result).endsWith("...");
assertThat(result).hasSizeLessThan(255);