Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a method on an Object from within a Class vs from within a method

Tags:

java

This might be a really elementary question but it puzzles me at this stage of my Java learning. I have got the following piece of code:

    package com.soti84;

    import java.util.ArrayList;

    public class InvokeMethod {

    public static void main(String[] args) {

    ArrayList<String> exams= new ArrayList<String>();
    exams.add("Java"); 
    exams.add("C#");    

    }           

    }

If I move the line that instantiates the ArrayList object and the calls on that object outside the method, the line that creates the object is fine but the add() method calls on the object are not allowed. Why is that?

    package com.soti84;

    import java.util.ArrayList;

    public class InvokeMethod {
    ArrayList<String> exams= new ArrayList<String>();
    exams.add("Java"); 
    exams.add("C#");    

    public static void main(String[] args) {

    }   

    }

Thanks.

like image 900
soti84 Avatar asked Sep 20 '16 09:09

soti84


2 Answers

You simply can't do that code outside of methods. If you wanted to do this you would need initializer block or static block.

public class InvokeMethod {
    ArrayList<String> exams= new ArrayList<String>();
    {
      exams.add("Java"); 
      exams.add("C#"); 
    }

Now that block is gonna execute when you create an instance. If your variable was static, you could make that block static (just add static before that block). Static block is gonna execute when your class is initialized. Those blocks can be quite convenient when you need a populated static list/map. Ofcourse, everything that is convenient in programming is probably a bad practice, and same here, those blocks are frowned upon by some people, they can be quite dangerous and lead to hard-to-find bugs (mostly about the order of execution).

like image 55
Shadov Avatar answered Oct 17 '22 07:10

Shadov


In the two examples you are trying to achieve two totally different things.

In the first example you declare the ArrayList inside the main method, therefore the scope of the list will be just this method. The enclosing class has absolutely no connection with that ArrayList.

In the second one you try to create a data member called exams in the class InvokeMethod. That means, every instance of this class will have its own list.

The addition of the elements does not work, because "out of the methods" only declaration and initialization can happen. To fix that, you can use an initialization block:

public class InvokeMethod {
    ArrayList<String> exams = new ArrayList<String>();
    {
        exams.add("Java"); 
        exams.add("C#");
    }

    public static void main(String[] args) {
    }   
}

or, the constructor of the class:

public class InvokeMethod {
    ArrayList<String> exams = new ArrayList<String>();

    public InvokeMethod() {
        exams.add("Java"); 
        exams.add("C#");
    }

    public static void main(String[] args) {

    }   
}

Note: You can also retrieve this list from main method via an instance of the InvokeMethod class:

public class InvokeMethod {
    ArrayList<String> exams = new ArrayList<String>();

    public InvokeMethod() {
        exams.add("Java"); 
        exams.add("C#");
    }

    public static void main(String[] args) {
        InvokeMethod invokeMethod = new InvokeMethod();
        System.out.println(invokeMethod.exams.toString());
        invokeMethod.exams.add("Delphi");
        System.out.println(invokeMethod.exams.toString());
    }   
}

will print

[Java, C#]
[Java, C#, Delphi]
like image 24
DVarga Avatar answered Oct 17 '22 08:10

DVarga