21

If you're defining a variable, it appears to be perfectly valid to declare/define a variable as follows:

    double[][] output = {{0,0},{1,0}};

But if you're returning a value, it appears to be invalid to write the following:

    public double[] foo(){
      return {0,1,2}
    }

I would have thought that internally, both of these would have been performing the same action. Eclipse, at least, disagrees. Does anyone know what the difference is, and where else it can be seen, or why it would be beneficial to accept the former example and reject the latter?

Edit: okay, so it's appropriate when you're initializing, but I don't see any ambiguity... couldn't the JVM interpret the type of variable from the name of the variable (in the case of redefining already initialized variables) or when returning (where the JVM could just look at the return type of the function)? What makes initialization a special case of a rule that would prohibit implicit type? What makes the general rule require explicit type?

John P
  • 1,463
  • 3
  • 19
  • 39
  • You brought up a good point. I be very interested in looking at the source code of the JVM when it comes to this behavior. – committedandroider Oct 13 '19 at 05:37
  • As others said, the Java creators designed it that way. It is demanded like that in the JLS. If you want to know the reason why, you will have to ask one of them. – Zabuzard Oct 13 '19 at 07:50

4 Answers4

22

You can use braces notation only at the point of declaration, where compiler can infer the type of array from the declaration type.

To use it anywhere else you need to use Array Creation Expression:

return new double[] {0,1,2};
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • 1
    "To use it anywhere else you need to use Array Creation Expression". Why? Why can't a return statement use the same notation? – John P Aug 03 '13 at 14:23
  • 1
    @JohnP. Because, the Java Language Creator designed it that way. See [JLS Section 10.6](http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.6). – Rohit Jain Aug 03 '13 at 14:32
  • 1
    No, I don't think so. If I asked why birds developed feathers instead of fur, saying "because the creator made it that way" would be nowhere near satisfactory, right? I'm more likely to accept Jeffrey's answer purely because you begged. – John P Aug 04 '13 at 14:52
  • @JohnP. Hah! Do you really take that as begging. It doesn't matter which answer you accept. I was just telling to accept the answer so that the answer can be considered solved for future visitor. This is a kind of vote of thanks we as a asker give to answerer. Where does begging come from. And if you take that last word- `please` as begging, then you don't understand the difference between begging, and being *polite*. – Rohit Jain Aug 04 '13 at 15:09
  • @JohnP. However, what kind of answer do you expect me to give you. How can I comment on the decision taken by the language creator, as to why they created it that way. Your reasoning is totally absurd. Still I've tried my best to explain the reason in my answer, if you read it carefully. Read the first line that says, *compiler can infer the type of array from the LHS of assignment*. It can't do that while method invocation or any other place apart from assignment for that matter. – Rohit Jain Aug 04 '13 at 15:11
  • @JohnP. Further than that, I don't think I or anyone else have the authority to reason more appropriately about this decision. – Rohit Jain Aug 04 '13 at 15:12
  • 2
    I was looking for the reasoning behind the language design. See http://www.oracle.com/technetwork/java/intro-141325.html section 1.2.1, last paragraph. C++ allows you to return a brace initializer since the type is already specified by the signature; Java should not only be able to do the same, but should be motivated to by the reasoning in my link (unless a technical reason prevents it, etc.) As for the 'begging', I reacted poorly 'accept *my* answer' rather than '*an* answer'. I'd like to apologize for it, two years late and all. – John P May 04 '16 at 21:24
  • 1
    @JohnP How does one submit a change to the Java platform for this kind of behavior? I don't change the syntax rule because that would break a lot of code but it be changed to accept both syntaxes and I think it should to be consistent with C++ as you mentioned – committedandroider Oct 13 '19 at 05:43
  • @RohitJain what does LHS stand for? And I'am curious who would have the authority to reason about the decision – committedandroider Oct 13 '19 at 05:44
  • @RohitJain - is there an alternate way to create an array like Arrays.create(1,2,3) ? – MasterJoe Jun 09 '20 at 00:11
16

It's only acceptable during a declaration. You can, however, use new double[] {0, 1, 2}.

JLS §10.6:

An array initializer may be specified in a declaration, or as part of an array creation expression.

An array creation expression is the new double[] { } syntax.

Jeffrey
  • 44,417
  • 8
  • 90
  • 141
  • 3
    "It's only acceptable during a declaration." Why? Why not during a return statement? – John P Aug 03 '13 at 14:23
  • 2
    @JohnP Because the language doesn't allow it. As far as I know, there is no good case against it (I guess the compiler might have to do a bit more type inference to ensure the creation is safe). – Jeffrey Aug 03 '13 at 22:06
  • 2
    @Jeffrey I get John's point though. The behavior should be consistent – committedandroider Oct 13 '19 at 05:35
  • @Jeffrey - is there an alternate way to create an array like Arrays.create(1,2,3) ? – MasterJoe Jun 09 '20 at 00:10
0

For whose still struggled like @committedandroider: Declaration and assignment are different things:

int[] arr = {1, 2, 3}; // This is valid [declaration]
arr = {2, 3, 4}  // This is invalid! [assignment]
Ufuk Bakan
  • 98
  • 7
-1

One more edge case I found was in the creation of a two dimensional array and initializing the arrays in the two dimensional array

So from Jeffrey's response - https://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.6 - "An array initializer may be specified in a declaration, or as part of an array creation expression", the below code should appear to work because the the array initializer is being used to initialize the array

int[][] grid = new int[3][3];
grid[0] =  {1,1,1};

However this didn't work(compilation error), and I had to rewrite this as

grid[0] =  new int[]{1,1,1};
committedandroider
  • 8,711
  • 14
  • 71
  • 126