[jboss-dev-forums] [Design the new POJO MicroContainer] - Re: ClassCastException for char[] MetaValue creation
scott.stark@jboss.org
do-not-reply at jboss.com
Wed Aug 8 13:04:30 EDT 2007
I have the following changes to the ArrayValue interface working and can preserve the primitive type arrays:
| public interface ArrayValue<T extends Serializable>
| extends MetaValue, Iterable<T>
| {
| ArrayMetaType<T> getMetaType();
|
| /**
| * Get the underlying array value. This will not be an
| * Object[] in general.
| * @see #getValue(int)
| *
| * @return the underlying value
| */
| public Object getValue();
| /**
| * Get the length of the array.
| * @return length of the array.
| */
| public int getLength();
| /**
| * Get the array element at index.
| * @param index - index into the array.
| * @return element at index.
| */
| public Object getValue(int index);
| }
|
As this ArrayValueSupportUnitTestCase test shows, you can use the getValue(int) accessor, the type safe foreach Iterable, or the raw array:
| public void testCharArray() throws Exception
| {
| ArrayMetaType<Character> type = new ArrayMetaType<Character>(1, SimpleMetaType.CHARACTER);
| char[] value = {'h', 'e', 'l', 'l', 'o'};
| ArrayValueSupport<Character> avs = new ArrayValueSupport<Character>(type, value);
| // Use getValue(int) accessor
| for(int n = 0; n < avs.getLength(); n ++)
| {
| Object element = avs.getValue(n);
| assertEquals(value[n], element);
| }
| // Use typesafe foreach Iterable
| int i = 0;
| for(Character c : avs)
| {
| assertEquals("["+i+"]", (Character) value[i++], c);
| }
| // Validate the primative array
| char[] raw = (char[]) avs.getValue();
| for(int n = 0; n < value.length; n ++)
| {
| assertEquals(value[n], raw[n]);
| }
| }
|
There are quirks for multi-dimensional primitive arrays though. This 2d char[][] test shows them:
| public void test2DCharArray() throws Exception
| {
| ArrayMetaType<Character[]> type = new ArrayMetaType<Character[]>(2, SimpleMetaType.CHARACTER, true);
| char[][] value = {{'h', 'e'}, {'l', 'l', 'o'}};
| ArrayValueSupport<Character[]> avs = new ArrayValueSupport<Character[]>(type, value);
| assertEquals(value.length, avs.getLength());
| for(int m = 0; m < value.length; m ++)
| {
| Object arraym = avs.getValue(m);
| for(int n = 0; n < value[m].length; n ++)
| {
| // Have to use the java.lang.reflect.Array to access nested elements
| Object valuenm = Array.get(arraym, n);
| assertEquals("["+m+"]["+n+"]", value[m][n], valuenm);
| }
| }
| // Use typesafe foreach Iterable: current broken with CCE on [C
| int i = 0, j = 0;
| for(Character[] carray : avs) // CCE here
| {
| for(Character c : carray)
| {
| Character cij = value[i ++][j ++];
| assertEquals("["+i+"], ["+j+"]", cij , c);
| }
| }
| // Validate the primitive 2d array
| char[][] raw = (char[][]) avs.getValue();
| for(int m = 0; m < value.length; m ++)
| {
| for(int n = 0; n < value[m].length; n ++)
| {
| assertEquals("["+m+"]["+n+"]", value[m][n], raw[m][n]);
| }
| }
| }
|
The first is that you have to use java.lang.reflect.Array.get(Object, int) to access the elements of the nested arrays obtained via the get(int) accessor.
The second is that the Iterable implementation on ArrayValueSupport needs to track whether the underlying value is a primitive array, and covert it to the primitive wrapper form to avoid the CCE.
Before going further I want to see if we agree that this is the way to go.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4072109#4072109
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4072109
More information about the jboss-dev-forums
mailing list