Search code examples
javascalaconcurrencystm

Java Scala-STM typecasting error when reading from TArray


I have a (ungraded) programming assignment in which I have to implement a circular queue using scala-stm from https://nbronson.github.io/scala-stm/.

I have a get function:

public E get() {
    E item = STM.atomic(new Callable<E>(){ public E call()
    {
        if (isEmpty()) STM.retry(); 
        E item = (E) items.refViews().apply(tail.get());
        //STM.increment(count, -1);
        return item;
    }});
    return item;

Now here I have to cast to E, (E) items.refViews().apply(tail.get()); or I get a compiler error. Which sort of makes sense. But in the unit test this item is tried to be casted to int, to verify that it's the same value as it was when put into the Circular Queue.

But I get the following classCastException:

java.lang.ClassCastException: class scala.concurrent.stm.ccstm.TArrayImpl$$anon$3 cannot be cast to class java.lang.Integer (scala.concurrent.stm.ccstm.TArrayImpl$$anon$3 is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')

Though the object was originally an integer, it can't be cast back. How should I go about it? I have studied the documentation in detail and it seems to actually do it in the same way, but for Strings. When I try strings, I don't get this exception anymore, but the cast back turns into the name of the TArray Object. I am doing something wrong, but I am not sure what. Thank you for any hints!


Solution

  • I found my mistake. This:

    E item = (E) items.refViews().apply(tail.get());
    

    Should be: E item = items.apply(tail.get());

    the .refViews().apply() returns a view object that is read only of the variable referenced in memory if I understood correctly. .apply() directly returns the actual object that the view is referencing in mem.