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).
Videos
You can also use String.format("%3.3s", "abcdefgh"). The first digit is the minimum length (the string will be left padded if it's shorter), the second digit is the maxiumum length and the string will be truncated if it's longer. So
System.out.printf("'%3.3s' '%3.3s'", "abcdefgh", "a");
will produce
'abc' ' a'
(you can remove quotes, obviously).
Use this to cut off the non needed characters:
String.substring(0, maxLength);
Example:
String aString ="123456789";
String cutString = aString.substring(0, 4);
// Output is: "1234"
To ensure you are not getting an IndexOutOfBoundsException when the input string is less than the expected length do the following instead:
int maxLength = (inputString.length() < MAX_CHAR)?inputString.length():MAX_CHAR;
inputString = inputString.substring(0, maxLength);
If you want your integers and doubles to have a certain length then I suggest you use NumberFormat to format your numbers instead of cutting off their string representation.
Im doing a college assignment and cannot figure how to put a max character length of 40 on a String
Some other answers have claimed that "There is no way to limit Strings in java to a certain finite number through inbuilt features", and suggested rolling ones own. However, Java EE validations API is meant for just this. An example:
import javax.validation.constraints.Size;
public class Person {
@Size(max = 6)
private String username;
}
Further info on how to use Validation API, see this thread for example. Hibernate validator is the reference implementation (usage).
In short, when annotating an object as @Valid, validations done in annotations will be enforced.
There is no way to limit Strings in java to a certain finite number through inbuilt features. Strings are immutable and take the value that you provide in their constructor. You will need to write code manually to do this.
Use the length() function to determine the length of the String and do not allow lengths greater than 6.
if( username.length() > 6 )
{
throw new RuntimeException("User name too long");
}
One of the options you have is to throw an exception and then handle it elsewhere. Or you can display an alert to the user immediately after you encounter the problem.
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);
Can anyone confirm if this is indeed a limitation of Java?
Yes. There is an implementation limit of 65535 on the length of a string literal1. It is not stated in the JLS, but it is implied by the structure of the class file; see JVM Spec 4.4.7 and note that the string length field is 'u2' ... which means a 16 bit unsigned integer.
Note that a String object can have up to 2^31 - 1 characters. The 2^16 -1 limit is actually for string-valued constant expressions; e.g. string literals or concatenations of literals that are embedded in the source code of a Java program.
If you want to a String that represents the first million digits of Pi, then it would be better to read the characters from a file in the filesystem, or a resource on the classpath.
1 - This limit is actually on the number of bytes in the (modified) UTF-8 representation of the String. If the string consists of characters in the range 0x01 to 0x7f, then each byte represents a single character. Otherwise, a character can require up to 6 bytes.
I think this problem is not related to string literals but to method size: http://chrononsystems.com/blog/method-size-limit-in-java. According to that, the size of the method can not exceed 64k.