1

So I'm trying to implement a CircularBuffer in Java, to which I can access the underlying array:

/* package protected */ class CircularBuffer<E> {
private final Object[] mArray;
private int mSize;
private int headPointer = 0;

private CircularBuffer(int size) {
  mSize = size;
  mArray = new Object[mSize];
}

private void add(E elem) {
  mArray[headPointer] = elem;
  headPointer = (headPointer + 1) % mSize;
}

public E[] getArray() {
  return (E[]) this.mArray;
}

}

I want to use this with Enums and various primitives (specifically booleans), but everything I call myEnum[] = myCircularBuffer.getArray(), I get a:

java.lang.ClassCastException: java.lang.Object[] cannot be cast to com.package.myEnum[]

Any tips on making something like this work?

Edit: I do know about the Apache CircularFifoQueue, but I don't want to use it since its way more than I need and I'm concerned about package size.

1
  • you cannot cast Object[] to myEnums straight away! Unless you make sure your mArray accepts type of objects that are either myEnum type or subclasses... Use generics Commented Aug 4, 2014 at 5:59

2 Answers 2

3

You have to make your internal mArray an array of the generic type E and not an array of Object. In order to do this you have to change your constructor to also get the Class of your generic E type. And also declare your mArray to be of type E[] which will help you to avoid further unneccessary casts (e.g. your getArray() method can simply return mArray without casting).

You can do that like this:

private final E[] mArray;

private CircularBuffer(int size, Class<E> type) {
    mSize = size;
    mArray = (E[]) Array.newInstance(type, size);
}

And you can use it like this:

CircularBuffer<String> buff = new CircularBuffer<>(10, String.class);
String[] arr = buff.getArray();
Sign up to request clarification or add additional context in comments.

Comments

0

You have an array whose runtime type is Object[]. It cannot possibly be E[] because arrays know their component type at runtime, and your class can't possibly know what E is, because it has no knowledge of it at runtime.

Imagine that if you could do it, then new CircularBuffer<E>(size).getArray() would be a backdoor way of doing new E[size], which is not possible in Java.

You can look at what the List interface in the Java standard library does. It also does not know the generic argument at runtime. It has two toArray methods: 1) one with no arguments that returns type Object[], and 2) one that takes a T[] argument and returns a T[]. The second one needs an array passed in to get the type T to construct the result array.

Comments

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.