[armedbear-devel] Losing type information after storing in java.util.ArrayList

Alessio Stalla alessiostalla at gmail.com
Tue Mar 23 18:16:23 UTC 2010


On Tue, Mar 23, 2010 at 2:55 PM, Mark Evenson <evenson at panix.com> wrote:
> On 3/23/10 7:21 AM, dmiles at users.sourceforge.net wrote:
> […]
>> A commiter should be able to help
>
> Patched as suggested in [r12570][1], although I am not entirely happy
> with this change yet (see below).
>
> [1]: http://trac.common-lisp.net/armedbear/changeset/12570
>
>> On Mon, Mar 22, 2010 at 9:55 PM, David Kirkman<dkirkman at ucsd.edu>  wrote:
>>> I've got a subtle problem:  if I create a byte array, store it in a
>>> java.util.ArrayList, and then retrieve the stored byte array, what I get
>>> back is not quite the same type as the original byte array.  I think that
>>> everything is the same, except that the JavaObjects have different values
>>> for the intendedClass field.
> […]
>
>>>
>>> Is there a way to specify the intendedClass of array2?
>
> A bit baroque, but one uses JCOERCE.  So, you could get your code to
> work via
>
>        (sys::%make-sys-output-stream
>            (jcoerce array2 (jclass-of array1)))
>
> but I think that this is a bit too much of a burden on the end user, so
> I patched the code as Douglas suggested.
>
> I've also updated the INSPECT protocol for JAVA-OBJECT so that users
> (and user code) could have a chance at observing that the two version of
> the array had differences in any tool that uses SYS::GET-INSPECTED-PARTS
> (like the SLIME inspector).
>
> As far as I understand this problem, the insertion/removal of the byte[]
> from the Java collection has erased the type information down to
> java.lang.Object.  This type is "good enough" for the current
> constructors of JAVA-OBJECT (after all java.lang.Object is a valid
> type), but causes problems when being asked to return a Java reference
> in compiled Java code (like that in the
> SYS::%MAKE-BYTE-ARRAY-OUTPUT-STRING.)
>
> My hunch is that need to tighten the JAVA-OBJECT constructors to check
> if they are being asked to wrap an array of primitive type, adjusting
> the value of intendedClass if this is the case.  I'm reluctant to make
> such a change as a) I don't fully understand the ramifications of the
> difference between Class.isInstance() and Class.isAssignableFrom(), b)
> don't know if this only fails for arrays of primitive type, and c) don't
> have enough test coverage to judge such things quickly.
>
> Comments and advice solicited.

I believe the isAssignableFrom check was just a plain mistake. The
"intended type" can be as generic as possible (i.e. it can be
java.lang.Object for any JavaObject) so it does not make much sense to
check against it. Imho it's correct to only do the isInstance() call.
Arrays of primitive types and arrays of corresponding wrapper types
are not interchangeable in Java so there should be no concern about
them in this context.

Note also that the intended type iirc is only used by jcall in its
abbreviated form - (jcall "methodName" instance args) - to access
methods using a supertype of the actual class of the object when
possible. This means that the intended type can be set quite loosely;
it's basically just a hint for jcall.

hth,
Alessio




More information about the armedbear-devel mailing list