anonymous array creation not a statement

I can usually create object instances without assigning them to any variable.

but not, it seems, if the object I'm creating is an array.

Are arrays the only objects for which this isn't allowed?

Paul Anilprem

Enthuware Software Support
Ranch Hand

Posts: 4059

33

posted 4 months ago

Interesting question. I tried find to something in the JLS about this but didn't find anything specific to this use case. When you create an unreferenced object of a regular class (such as new String() or whatever), you are doing it for the side effects of the constructor because the object itself will most probably be garbage collected. You should not rely on this though because the JVM may even optimize the call away. So logically, it doesn't make sense to create unreferenced array objects because these array classes do have any user defined code. Other than this, I don't see any reason why this is prohibited.

Paul Anilprem wrote:When you create an unreferenced object of a regular class (such as new String() or whatever), you are doing it for the side effects of the constructor because the object itself will most probably be garbage collected. You should not rely on this though because the JVM may even optimize the call away.

So I can't be sure that the Dog will bark?

I thought that was guaranteed.

Paul Anilprem

Enthuware Software Support
Ranch Hand

Posts: 4059

33

posted 4 months ago

Richard Hayward wrote:

Paul Anilprem wrote:When you create an unreferenced object of a regular class (such as new String() or whatever), you are doing it for the side effects of the constructor because the object itself will most probably be garbage collected. You should not rely on this though because the JVM may even optimize the call away.

So I can't be sure that the Dog will bark?

I thought that was guaranteed.

I think this is guaranteed. But I am unable to find a definitive source that lists what all is guaranteed. I am sure other experts here will point you to the right source.

Block: A Block may consist of one or more BlockStatements. A BlockStatement may be either a LocalVariableDeclarationStatement, a ClassDeclaration or a Statement. You already know that you can initialize arrays like this in local variable declarations, and class declarations are not applicable. Let's explore Statement: If we go through the list of things that a Statement can be, the only one that appears like it could be applicable to your situation is the ExpressionStatement. Here's the list of things that an ExpressionStatement can be when terminated by a semi-colon:

Assignment

PreIncrementExpression

PreDecrementExpression

PostIncrementExpression

PostDecrementExpression

MethodInvocation

ClassInstanceCreationExpression

You're not performing assignment, an increment/decrement operation, a method invocation or class instance creation. Creating an instance of an array is not allowed as a statement by itself. You need to assign it to a variable, and it doesn't matter whether you use an array initializer or not.

The reason why class instance creation is allowed as a statement by itself, is because constructors can have side effects that a programmer may wish to occur, without doing anything with the new instance. This is not recommended behavior, but APIs are sometimes horribly designed. Array creation never has side-effects though, so creating one without assigning it to a variable is always a mistake.

The mind is a strange and wonderful thing. I'm not sure that it will ever be able to figure itself out, everything else, maybe. From the atom to the universe, everything, except itself.

Stephan van Hulst

Saloon Keeper

Posts: 7469

133

posted 4 months ago

I'm pretty sure class instance creations are never optimized away. They might be inlined though, and parts of their inlined code may be optimized away. Side effects will never be removed.

The mind is a strange and wonderful thing. I'm not sure that it will ever be able to figure itself out, everything else, maybe. From the atom to the universe, everything, except itself.

so an array, although an object, isn't a class instance. That seems odd to me on two counts.
Firstly, I can take an array object and ask what its class is, an int[] will report its class as being [I
Secondly if I get an array's class and then use reflection to examine its constructors, I find that it hasn't got any, so I don't see how the array could have been created.

However, for the purposes of passing the exam, this seems territory that I won't get tested on, so with thanks to Paul & Stephan, I'm happy to leave it at that.

Every array has an associated Class object, shared with all other arrays with the same component type.

Although an array type is not a class, the Class object of every array acts as if:

The direct superclass of every array type is Object.

Every array type implements the interfaces Cloneable and java.io.Serializable.

The mind is a strange and wonderful thing. I'm not sure that it will ever be able to figure itself out, everything else, maybe. From the atom to the universe, everything, except itself.

Stephan van Hulst

Saloon Keeper

Posts: 7469

133

posted 4 months ago

Richard Hayward wrote:if I get an array's class and then use reflection to examine its constructors, I find that it hasn't got any, so I don't see how the array could have been created.

Constructors are members of classes, and arrays aren't class types. Arrays are created using black voodoo magic, the same way instances of Cloneable classes are created when you clone an original.

The mind is a strange and wonderful thing. I'm not sure that it will ever be able to figure itself out, everything else, maybe. From the atom to the universe, everything, except itself.

Richard Hayward

Ranch Hand

Posts: 170

11

posted 4 months ago

Thanks for your help, explanations & links Stephan. That covers my concerns & I'll have a look through that bit of the jls.

Incidentally, looking at the code I posted earlier, to find the constructors in an array class, I should have usedto capture all of them: public, protected, default & private. Makes no difference to my problem (now explained) however, using reflection still reports no constructors.