3

I have three different ways of declaring my string array in Java. One works all the time but the other two only work depending upon the order in which they are written.

In the first version, method2 does not work but method3 does.

public class weirdStringArray {

    String [] method1 = new String [] {"one","two","three"}; //<------ Works no matter where it's placed

    String [] method2;       //<------ "Syntax error on token ";", { expected after this token"
    method2 = new String[3]; //  Doesn't work in this postion
    method2[0] = "one";
    method2[1] = "two";
    method2[2] = "three";

    String [] method3 = new String[3]; //<-------  No issue, works fine in this position
    method3[0] = "one";                
    method3[1] = "two";
    method3[2] = "three";
} // <----- Syntax error, insert "}" to complete ClassBody (but it does seem to complete ClassBody...?)

But, switch positions and the working declarations swap too. Look, now method2 works but method3 doesn't.

public class weirdStringArray {

    String [] method1 = new String [] {"one","two","three"};

    String [] method3 = new String[3]; //<------ "Syntax error on token ";", { expected after this token"
    method3[0] = "one";               //  Doesn't work in this postion
    method3[1] = "two";
    method3[2] = "three";

    String [] method2; //<---------- Put it in a different place and it works
    method2 = new String[3]; 
    method2[0] = "one";
    method2[1] = "two";
    method2[2] = "three";

} // <----- Syntax error, insert "}" to complete ClassBody (but it does seem to complete ClassBody...?)

What might be happening here ? Why would the order make any difference ? What's happening in position 2 ? Incidentally, it makes no difference if I remove the first working form:

public class weirdStringArray {

    //String [] method1 = new String [] {"one","two","three"};

    String [] method2;        //<------ "Syntax error on token ";", { expected after this token"
    method2 = new String[3]; //  Doesn't work in this postion 
    method2[0] = "one";
    method2[1] = "two";
    method2[2] = "three";

    String [] method3 = new String[3]; //<-------  No issue, works fine in this position
    method3[0] = "one";               
    method3[1] = "two";
    method3[2] = "three";

} // <----- Syntax error, insert "}" to complete ClassBody (but it does seem to complete ClassBody...?)
1
  • 1
    It's just a misunderstanding about how Java works. You cannot put random code inside a class body, except for instantiation code, most of the logic must go inside methods. Commented Mar 14, 2020 at 12:30

6 Answers 6

1

Try this to get it working as you might have intended it:

public class weirdStringArray {

    String [] method1 = new String [] {"one","two","three"}; //<-- Works no matter where it's placed, because this is a valid one line initialisation

    String [] method2;
    {
        // We gave it the '{' the compiler asked for …
        method2 = new String[3];
        method2[0] = "one";
        method2[1] = "two";
        method2[2] = "three";
    }

    String [] method3 = new String[3];
    {
        method3[0] = "one";                
        method3[1] = "two";
        method3[2] = "three";
    } // <-- … and this is the missing '}'
}

These '{…}' blocks are initialiser blocks, better known/more often used in their static variant, as 'static {…}' for static final attributes. That's because the code in those initialisers is usually better placed into a constructor.

The advantage of using these initialisers is that they are executed before all constructors, the disadvantage is that they are executed before all constructors. Best seen when you play with final attributes …

They work fine for all constant initialisations, like in the sample here, and other types of (potentially) never failing initialisations. Calling non-static methods from here should be avoided, and calling non-static methods of the current class does not work at all (this was not yet initialised as you are currently initialising it …).

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

Comments

1

These types of statements are not allowed in class bodies. Wrap them in a method body first.

Comments

1

Apart from initializing it, you simply cannot do anything to an instance attribute (no matter if it's an array, or anything else) if it's "outside" of a method or a constructor. This is what you want to do:

public class weirdStringArray {

    String[] method1 = new String[] {"one", "two", "three"};
    String[] method2 = new String[3];
    String[] method3 = new String[3];

    public weirdStringArray() {
        method2[0] = "one";
        method2[1] = "two";
        method2[2] = "three";
        method3[0] = "one";
        method3[1] = "two";
        method3[2] = "three";
    }

}

Or, alternatively you could use initialization blocks:

public class weirdStringArray {

    // this way also works, it counts as initialization
    String[] method1 = {"one", "two", "three"};

    String[] method2 = new String[3];
    {
        method2[0] = "one";
        method2[1] = "two";
        method2[2] = "three";
    }

    String[] method3 = new String[3];
    {
        method3[0] = "one";
        method3[1] = "two";
        method3[2] = "three";
    }

}

2 Comments

Thanks very much, that's really helpful. But why does the first version work ? It seems like I'm doing more than just initializng the array in this one line ?
@user7390817 the first version works because you're instantiating the object in a single line - yes, it's doing nothing more than initializing the array with some given values. To put it another way: any other line besides the single line where you declare and initialize an attribute, must go somewhere else. A constructor, an initialization block, or a method.
1

Note that except for the instantiation, you can not put code inside the body of a class. Check the following code for an example:

public class weirdStringArray {
    String[] method1 = new String[] { "one", "two", "three" };

    {
        String[] method2;
        method2 = new String[3];
        method2[0] = "one";
        method2[1] = "two";
        method2[2] = "three";

        String[] method3 = new String[3];
        method3[0] = "one";
        method3[1] = "two";
        method3[2] = "three";

        String[] method4;
        method4 = new String[3];
        method4[0] = "one";
        method4[1] = "two";
        method4[2] = "three";
    }

    public static void main(String[] args) {
        String[] method2;
        method2 = new String[3];
        method2[0] = "one";
        method2[1] = "two";
        method2[2] = "three";

        String[] method3 = new String[3];
        method3[0] = "one";
        method3[1] = "two";
        method3[2] = "three";

        String[] method4;
        method4 = new String[3];
        method4[0] = "one";
        method4[1] = "two";
        method4[2] = "three";
    }
}

This code compiles without an issue because whatever code I have put outside a method is for initialization. If I remove {} boundary from the initialization code in the body of the class, the code will fail compilation. Check Initializing Instance Members section for more information.

Comments

1

TL;DR: Move your entire code block inside a function; this problem would cease to exist immediately.



The only thing you can do to a variable outside of a method/function body is to initialize it, but even at that, you need to do that on the same line you're declaring the variable. You are facing this problem because you're trying to perform actual operations outside of a function block. Let's look at each approach one by one...

First approach:

String [] method1 = new String [] {"one","two","three"};

The approach above works just fine because you're performing declaration and initialization at the same time. No rule has been broken here.

Second approach:

String [] method2;       //<------ "Syntax error on token ";", { expected after this token"
method2 = new String[3]; //  Doesn't work in this postion
method2[0] = "one";
method2[1] = "two";
method2[2] = "three";

At line two, you are performing an operation on a variable you declared in the previous line. This cannot be done outside of a function. Hence, the error.

Third approach:

String [] method3 = new String[3]; //<-------  No issue, works fine in this position
method3[0] = "one";                
method3[1] = "two";
method3[2] = "three";

This third example is expected to work well. Here's why: The first line represents a valid way of declaring and initializing a variable. Even though the subsequent lines are array element initializations, they still count as valid ways of initializing variables because array elements are treated as independent entities in this context.



Remember that the key point here is to make sure all post-declaration code is wrapped up inside a method/function body.

Comments

0

You should put value assignment operation in function body if it does not consists of a single line like method2 and method3. Java doesn't allow this.

Comments

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.