0

base.buffer.length in the main method throws an exception, whereas isFull method works, can someone please help me understand what is going on?

package chp14;

public class BaseBoundedBuffer<V> {
    private final V[] buffer;
    private int head, tail, count;

    public BaseBoundedBuffer(int capacity) {
        this.buffer = (V[]) new Object[capacity];
    }

    public boolean isFull() {
        return buffer.length == count; // But this works
    }

    public boolean isEmpty() {
        return count == 0;
    }

    public static void main(String[] args) {
        BaseBoundedBuffer<String> base = new BaseBoundedBuffer<>(10);
        System.out.println(base.isFull());
        int count = base.buffer.length;
        // This line throws an exception, but the method isFull works, why?
        // Exception in thread "main" java.lang.ClassCastException:
        //      java.base/[Ljava.lang.Object; cannot be cast to java.base/[Ljava.lang.String;
        //          at chp14.BaseBoundedBuffer.main(BaseBoundedBuffer.java:21)

    }
}
Michael
  • 34,340
  • 9
  • 58
  • 100
  • A `V[]` is not an `Object[]` so you are getting a class cast exception. If you look at the source code for [Arraylist](https://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/util/ArrayList.java) you can see they just keep an Object[] to back their data. – matt Jan 14 '19 at 17:09
  • 1
    Because when you built variable base as a BaseBoundedBuffer you indicated that the type parameter used for V in class BaseBoundedBuffer is String. Therefore when accessing field base.buffer it is to be seen as type String[]. But it is as a result of generics. In raw types it is type Object[], so to be seen as String[] a cast is necessary, therefore it is done. And the cast fails with ClassCastException, because the array you built was not type String[]. – kumesana Jan 14 '19 at 17:09
  • @kumesana, they why does isFull() method succeed? – Vijay Narayanan Jan 14 '19 at 17:26
  • 1
    isFull() is a method. Accessing it does not trigger the mechanisms I talked about. A method has no type that might be generic and need to be casted to another type as a result of being generic. – kumesana Jan 14 '19 at 17:35
  • I agree the op is trying to create a generic array, so the question is somewhat moot, but I cannot tell which of the other answers, answers this question? Why does the exception happen at one location and not at the other? – matt Jan 14 '19 at 19:18
  • @matt, yes, that's exactly my question. – Vijay Narayanan Jan 14 '19 at 19:55
  • 1
    I haven't found why, but they address it here, https://softwareengineering.stackexchange.com/a/331109 . I think it is what kuesana was getting at. Everything internal uses type erasure, so the V[] is an object. Once you expose that to external code, such as `static main` the array is cast to the concrete type. Which it isn't, it is actually an Object[] due to the type erasure. – matt Jan 14 '19 at 20:16
  • @matt, thanks the link you suggested answers my question! :) – Vijay Narayanan Jan 14 '19 at 20:23

0 Answers0