12

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?

1

4 Answers 4

13

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.

Sign up to request clarification or add additional context in comments.

5 Comments

I don't think that's completely right. I think that Object obj = {new Object(), ...} returns an array, as in "a multiple pointer-array", while new ... returns a pointer to whatever comes after new. So Object obj = new Object[]{...} returns a pointer to the array, while Object obj = {...} returns an array.
@Danyel: A variable never actually contains an array in Java, it always contains a reference (loosely, "pointer") to the array (as with any other object).
@Crowder: Yes, technically, that is how it's done, but that doesn't mean it's done that way internally, too? I'm saying that's why the compiler might have some issues interpreting that. It's only assumptions, too, so unless we get a JLS quote, it's pretty much senseless arguing. (although... does JLS provide information about how it's implemented / done internally?)
@Danyel: The JLS defines what variables hold, yes. And it has to be done that way internally, otherwise the semantics of the language would break down. Consider: Object[] a; Object[] b; a = new Object[] { new Object(), new Object() }; b = a; b[0] = null; System.out.println("a[0] is null? " + (a[0] == null)); If the variables actually contained the array, the b = a; line would have to be an array copy operation, wouldn't it? And thus assigning to b[0] would have no effect on a[0]. But of course it does, because Java defines that a and b hold references. :-)
Yes, I know that. I wasn't actually doubting/questioning that. The ultimate question would be, for me, if Object[] o = {...} is stored in the Stack or the Heap of the application. I think that's where I'm trying to get. I know that in the end o will only be a reference and not the actual array. I hope you know what I mean.
9

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).

5 Comments

@Robber: I said "not just".
"Array is not just a subclass of Object" => But it is a subclass, you agree, so you haven't explained why this doesn't work, and in fact it does work (see Robber's answer). "Arrays also have language-level semantics and syntax" => Vaguely quoting the entire JLS chapter on arrays is just proof by intimidation. "You've just declared an object, but it has no named fields, and lacks the numerically-indexed slots arrays have." => You haven't "declared an object"; you've declared a variable of type Object, which may be pointed at any Object instance. Variables never have fields anyway.
@Boann: I agree that Robber seems to have zeroed in on the relevant aspect of the question more successfully than I did, and +1 to him/her for that! The original (pre-edit) question was less clear, but still, I think Robber picked it up even from that.
Thanks, much of what you wrote makes perfect sense. @Boann: You nailed what I would have liked to reply if I was able to come up with such a razor sharp formulation.
1

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).

Comments

0

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

8 Comments

Robber's answer proves yours wrong, I'm afraid. Thanks for offering an answer, anyway.
Why do you think I am wrong here? Can you explain I want to know?
@vamsilp: Object variables can hold references to arrays, because arrays derive from Object. You don't have to declare the variable Object[] (although it's likely to be more useful if you do). It's just that when creating and initializing the array, the compiler needs to know what type of array it is, hence the syntax Robber presents.
@T.J Crowder now when you say that Object variables can hold references to arrays and I don't have to declare variable as Object[] why cant I go ahead and declare a String string=new String[] {new String(),new String()}; even though a String is also an object and here string is a String variable? Why does Object obj = new Object[] { new Object(), new Object() }; work and the same cant work for String?
@Student: I guess we both were right and we both were wrong due to my answering of only one alternative of your question. I will go ahead and edit my answer to include Robbers version also to make it clearer.
|

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.