29

I was going through an open source project where they were creating an output stream, and came across the following method:

@Override public void write(byte[] buffer, int offset, int length) {
    if (buffer == null) {
        throw new NullPointerException("buffer is null");
    }
    if (buffer.length < 0) { // NOTE HERE
        throw new IllegalArgumentException("buffer length < 0");
    }
    if (offset < 0) {
        throw new IndexOutOfBoundsException(String.format("offset %d < 0", offset));
    }
    if (length < 0) {
        throw new IndexOutOfBoundsException(String.format("length %d < 0", length));
    }
    if (offset > buffer.length || length > buffer.length - offset) {
        throw new IndexOutOfBoundsException(String.format("offset %d + length %d > buffer"                                                       " length %d", offset, length, buffer.length));
    }
}

So the byte[] buffer is just a normal old byte[]. We know it's not null. Is it even possible to make it have a length of less than 0? Like, could it be done with reflection and that's what they're guarding against?

20
  • 3
    @EdwardThomson: I think because the first statement checks buffer == null Commented Jul 17, 2012 at 20:02
  • 4
    @thalador There can be no such convention. You physically cannot make array.length < 0. Commented Jul 17, 2012 at 20:06
  • 3
    @thalador There are plenty of cases when an int can be -1. There are zero cases when an array's length can be -1 (which is what's being checked here). Commented Jul 17, 2012 at 20:11
  • 2
    What's strange with this method is that it writes nothing. Was the author too occupied by the assertions to write something useful ? Commented Jul 17, 2012 at 20:13
  • 1
    @a_horse_with_no_name I've seen plenty of those, too, and wrote some myself as well, but always in cases where the language will have no issue with that var being < 0. The check at hand is on the order of checking that an unsigned value is < 0 -- say you check that a char is < 0. Commented Jul 17, 2012 at 20:32

3 Answers 3

35

No, this can never happen. The length is guaranteed to be non-negative as per the Java specifications.

The members of an array type are all of the following:

  • The public final field length, which contains the number of components of the array. length may be positive or zero.

Source: JLS §10.7

As mprivat mentioned, if you ever try to create an array of negative size, a NegativeArraySizeException will be thrown.

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

1 Comment

@Reimeus: Because programmers never make any mistakes and always write the most optimal code.
7

I don't believe it's possible. Even through reflection, it is guarded with NegativeArraySizeException

4 Comments

I made an effort to alter the length of an array reflectively, but found myself unable to do so. The getDeclaredFields() method returns an empty result for an array input, and the Array reflection class understandably has no such method (because why would you ever want it?) I think short of modifying memory directly there'd be no way to do this, but I doubt there's actually a check that would prevent this. Of course, if a program is modifying memory on you, you have bigger problems than you can catch with a parameter check...
Yeah, I think that was just bad code. The only to make this happen would be to do some sort of byte code modification somehow. And frankly, even with that, I'm not 100% sure you could if the length is somehow coded as an unsigned number (which I suspect is the case).
I don't think it is, because you can't compile int[] a = new int[3000000000]; - I suspect it is stored as an int like any other.
You're definitely right. Because int[] a = new int[-1]; does compile. Of course it doesn't run as expected but it compiles. Plus there's no such thing as an unsigned int in the JVM. Duh. Good question though.
0

This is just an exception handling issue. You're allowed to create an array with a negative size in Java - it wont even throw an exception when you compile it. But at run time, your program won't run until this is corrected. (It will throw a NegativeArraySizeException.)

The problem is with this exception being thrown at run time instead of compile time - That's why the exception has been handled with IllegalArgumentException.

1 Comment

"You're allowed to create an array with a negative size in Java" - no, you are not. You can write new int[-1] but the JVM will not create such an array. No Java array object will ever have a negative length.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.