Multidimensional Object array behaviour - java

I am trying to understand some fundamentals about arrays. I thought multidimensional arrays were really just arrays of arrays. With that in mind, I don't understand the following behavior:
Object [] object = {new Object[1]};
Object anotherObject = object[0][0]; //doesn't work
Object yetAnotherObject = object[0]; //does work
I am confused why the second line does not compile ("Array type expected"). I thought since "object[0]" was in fact an object array, I could use the square brackets to access its contents.
What am I missing?

The type of object is Object[], which is a 1 dimensional array. The fact that you store an array element in that array doesn't make it a 2 dimensional array.
Object anotherObject = object[0][0];
doesn't work since the compiler doesn't know that object[0] is an array (and it doesn't have to be - object[0] can hold a reference to any Object).
You'll need casting in order for it to work:
Object anotherObject = ((Object[])(object[0]))[0];

Related

Java - Casting ArrayList<Object[]> to Object[][]?

Ok, so here's a small problem I'm facing - is there an easy way in Java to cast
ArrayList<Object[]> array;
to
Object[][] data;
?
Object[][] data=array.toArray();
The Object[]'s inside are treated as a type of object themselves. They then are put into their own array, leading to an array of array objects of objects, or simply a two-dimensional array.
Casting is not the solution you are looking for. Casting would essentially allow you to use a method that you cast to a specific class type. An example of a cast:
(((ClassA)classB).method())
So a returned value can be placed inside of a ClassA object from the instantiated classB object that contains method().
What you are wanting to do on the other hand is create a multidimensional array or a 2D array. This is essentially an array of arrays, where arrayA[i] = arrayB[];
For example:
Object[] objectArray = new Object[5];
Object[][] = objectArray2D = new Object[][];
objectArray2D[i] = objectArray;
Here is a point to your question though, if you create a multidimensional array, why would you feed it only one array instance. Essentially what you would create in the above example is an array inside of an array, and since you will be giving it only 1 array indexing of all the objects inside the array would be the same as if you had the one array, but with one additional placement. Let me explain:
objectArray[0] == the object you placed on the first slot of objectArray
while objectArray2D[0][0] == the exact same object as the object in objectArray[0]
You are not receiving any advantage by using a multidimensional array for one array. If you were to ask the 2D array for the index [1][0] you would receive an out of bounds exception.
Lastly, I would suggest that you create a specific form of array, such as int[], or string[]. The problem with a Object[] array is that you can store anything that is considered an Object into the array, allowing for a potential cluster of different types of Objects inside one array. Example you could have a objectArray[0] = int 1; and objectArray[1] = String one; Unless you want to be very specific in the array use, it might be better to use one Object type as the array.
In any case the final solution to do exactly what you are wanting to do is as follows:
ArrayList<Object[]> array;
Object[][] data;
public void changeToAnArray(ArrayList<Object[]> array, Object[][] data)
{
this.array = array.toArray();
this.data[0] = array;
}
Also due note the point of an ArrayList, is to have a 2D array in essence without having to parse the indexes.
Please anyone feel free to correct on the parts I am wrong on << still learning.

Java : Why can't I declare an array as a simple Object?

In Java, I can compile
Object[] obj = {new Object[1], new Object[2]};
But I cannot compile
Object obj = {new Object(), new Object()};
In the first example I declare a one-dimensional array of Objects and assign it a two-dimensional array. In the second I declare an Object and assign it a one dimensional array.
If a Java array extends Object, why doesn't the second code fragment compile? Why does the first?
Assigning an array to an Object isn't a problem, but you have to create the array like this
Object obj = new Object[] { new Object(), new Object[2] };
Otherwise the compiler won't know that it's an Object array and not some other kind of array.
Because Array is not just a subclass of Object. Arrays also have language-level semantics and syntax.
Separately, your second example begs the question: Where would the object store those two things you're trying to initialize it with? You've just declared an object, but it has no named fields, and lacks the numerically-indexed slots arrays have.
Your first example compiles because you've declared an array of Object (which is to say, object references), and the elements you're giving it to initialize that array are object references (references to the single-element arrays you're creating via new Object[1]).
This may help as well: Java doesn't really have two-dimensional arrays, although there is some convenience syntax that makes it look like it does. It has (single dimensional) arrays of (single dimensional) arrays (of...you get the idea).
The problem is that when you create an array using an initializer, the compiler needs to ensure all elements from the initializer are of the same provided type by checking the type of the element against the provided type.
That said, you always need to provide the type information when initializing an array. Otherwise, the compiler doesn't know how to verify if the array initialization is valid, thus giving an illegal initializer error.
There's no problem assigning an array to an object. For example, you can do the following:
int[] arr = {1,2};
Object obj = arr;
The following code won't compile:
Object obj = {1,2};
Because you didn't explicitly provide the type of the element that the compiler needs to verify the values in the initializer against. And this is required for array initialization in Java.
The following code will compile:
Object[] obj = {1,2};
Because the type of the element was provided(i.e.,Object) and the compiler will check the type of 1, 2 against the type Object(which succeeds since Integer is subtype of Object).
You cannot compile
Object obj = {new Object(), new Object()};
because obj is not an array therefore declare like this
Object[] obj = {new Object(), new Object()};
or
Object obj = new Object[] { new Object(), new Object() };
Edited after the below conversation

How can you store an array object in a single reference of Object class?

As far as my understanding goes Object is also a class in java. So,how is it that we can write
Object ob = new Integer[2];
and not
Integer i = new Integer[2];
How is it that a single reference ob can point to array of Integers but reference of type Integer can't?
Because every array is an object. So polymorphism rules tell us that Integer[] (array of Integer) can be stored in an Object, but obviously Integer[] (array of Integer) can not be stored in an Integer.
From JLS#Chapter 10. Arrays
In the Java programming language, arrays are objects (§4.3.1), are dynamically created, and may be assigned to variables of type Object (§4.3.2). All methods of class Object may be invoked on an array.
All the components of an array have the same type, called the component type of the array. If the component type of an array is T, then the type of the array itself is written T[].
Because every array is a subtype of Object. But no array is a subtype of Integer.
Since the following expression on the RHS creates an array object: -
new Integer[2];
So, your reference type on the LHS should be compatible to be able to hold a reference to an array.
Now, since array in Java is a subtype of Object, so an Object type can hold a reference to an array.
But, an Integer reference of course cannot point to an array.
So,
Object ob = new Integer[2]; // is valid. as `Object` type reference can point to an array object
Integer i = new Integer[2]; // is not valid. as `Integer` type reference cannot point to an array object.

Object type in Java and referencing arrays

public class RefMix {
public static void main(String[] args) {
Object[] a = {null, "foo"};
Object[] b = {"bar", b};
a[0] = b;
System.out.println(a[0][0]);
}
}
My understanding is that arrays are objects in Java, and therefore a subclass of the Object type. My further understanding is that a 2-dim array is implemented as an array of references to arrays. Therefore I don't understand why my a[0][0] does not produce bar in the code above. Instead it doesn't compile:
RefMix.java:7: array required, but java.lang.Object found
My understanding is that arrays are objects in Java, and therefore a subclass of the Object type. My further understanding is that a 2-dim array is implemented as an array of references to arrays.
This is all correct and explains why you can do the assignment
a[0] = b;
without any complaints from the compiler.
Therefore I don't understand why my a[0][0] does not produce bar in the code above.
Okay, let's take a look at the types in this expression:
a is a Object[] -- that is an array of Objects
a[0] is an Object
a[0][0] -- Now you are trying to use an array subscript on an Object. The compiler does not know that the Object is in fact an array, so it complains.
The runtime type of an object instance differs from the statically inferred type. The compiler will try to estimate what type each variable could be in the program, in order to catch certain types of errors early. In this case, a[0] will always be an array, but the compiler doesn't know this. Since you are getting an object out of an object array, all the compiler knows is that a[0] is an object. Therefore it raises an error.
In cases where you know something will always be a certain type but the compiler can't figure it out, you can get around this by inserting an explicit cast.
System.out.println(((Object[])a[0])[0]);
You are right, arrays are always Objects in Java, but Objects are not always arrays, therefore you get a compile error, because a is an Object[] (one dimensional). You can not access
a[0][0];
because a is not a two dimensional array (at least it's not declared as such). However in this case, you are sure, that a[0] is an array of Objects. Therefore, you can do this:
Object[] c = (Object[]) a[0];
System.out.println(c[0]);
// or directly:
System.out.println(((Object[])a[0])[0]);
This casts the return type of a[0] (which is Object), into a Object[] and you can then access the "second layer" of the array.
Since array in Java is an object, so the 1st and 2nd assignment, will store your array as the 1st element of your Object array..
Object[] a = {null, "foo"};
Object[] b = {"bar", b};
Now, you have changed your 1st element of a object array to contain value b instead of array.. But since it is an array of object. Everything coming out of it will be object..
Since a[0] is an object..
So, you clearly can't access something like this: -
System.out.println(a[0][0]);
You can try to typecast your object a[0] to object array..: -
System.out.println(((Object[])a[0])[0]);
Do:
System.out.println(((Object[])a[0])[0]);
This will "cast" the object to an object array at runtime.
As I do a lot of C++ coding lately, I find that Java is a lot more strict in type checking then C++ is. Java sees everything but primitive types as Object but Java goes one step further in distinguishing Array and non-Array types. During assignment like "a[0] = b;" , Java first check to see if it is an Array type or not, after that it goes through regular polymorphic type checking procedure. If you wish to make your code work, you should do...
Object[][] a = {{null}, {"foo"}};
Object[] b = {"bar", new java.util.Date()};
a[0] = b;
You can see how java take special care on array types by looking into Java Class signature that is passed to Class.forName() as parameter. For example, data type ..
com.foo.Bar[][] barsIn2D;
can be loaded with signature below...
// [ => Array
// [[ => Array of Array type
// L<object>; => Object, not Array
Class.forName("[[Lcom/foo/Bar;");
As you see, signature starts with either '[' or 'L'.
This tells us whether its an array or not takes precedence over "Lcom/foo/Bar;".
Everything that you are doing is equivalent to this
Object a = {"bar", "foo"};
System.out.println(a[0]);
which doesn't compile either.

Resolving ClassCastException in this code

I have this method getData as shown .
It is expecting an array of bag Objects as shown
please see the code below :
public static String getData(Bag[] bag)
{
}
public class Bag
{
public char side;
}
But , when i tried i am getting ClassCastException .
I have done this way :
Object bagArray[] = new Object[1];
Bag bagData = new Bag();
bagData.side = 'S';
bagArray[0]=bagData;
String bagData = ApplicationUtil.getData(Bag[]) bagArray);
Please let me , how to resolve this error ??
Why are you creating an Object array rather than an array of Bag objects?
Try just changing the first line to Bag[] bagArray = new Bag[1].
As an Object array can hold any kind of object, so I don't think it can be cast to a Bag array. You could however cast bagArray[0] to a Bag object.
In future, try using a List or other collection rather than an array for stuff like this.
The problem is that bagArray is an array of Object and not an array of Bag.
Either change that to Bag bagArray[] = new Bag [1]; or use a Collection (e.g. List) instead - note that you can cast List<Object> to List<Bag> but that is an unsafe operation and not recommended unless you know what you're doing.
You're trying to cast an Object[] into a Bag[]. Not allowed.
You bagArray is an Object array and not a Bag array. Just because it is capable of holding an object of type Bag (which is a subclass of Object), does not mean the vice versa. You are trying to cast Object to Bag type, which is not allowed. Define you bag array in the following way
Object bagArray[] = new Bag[];
See this question: Quick Java question: Casting an array of Objects into an array of my intended class
As others have said, you can't cast an Object[] to, well, anything. In this case, you have a Bag inside an Object array, so in this specific instance it seems like it might work. But imagine that you had a larger array, full of objects of different types. In that case, the cast wouldn't work. The program has to work for the general case.
You can solve this by:
1) Using a Bag[] type instead of Object[]
2) Using a List - collections are nearly always better
3) Using the Arrays class to create a new Bag[]: Arrays.copyOf(bagArray,bagArray.length,Bag[].class)

Categories

Resources