0

I want to be able to get input from the scanner class within one instance method and than pass it to another instance method where I will display it.

Here is an example of my problem

    import java.io.*;
    import java.util.*;

    class TestScanner
    {
       public static void main (String args[])
       {
          TestScanner disInput = new TestScanner();
          TestScanner gInput = new TestScanner();
          gInput.grabInput();
          disInput.displayInput();


       }

       void displayInput()
       {
          System.out.println("Scanner Input here: ");
          System.out.println("What is my age: ");
          // How do I get age here
          System.out.println("What is 2 +2: ");
          // How do I get math here
       }

       void grabInput()
       {
         int age, math;
         Scanner stdin = new Scanner(System.in);

         System.out.println("What is my age: ");
         age = stdin.nextInt();
         System.out.println("What is 2 +2: ");
         math = stdin.nextInt();

       }
    }
Jets
  • 7
  • 3
  • 1
    Check [Passing Information to a Method or a Constructor](https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html). Also, check [Why are static variables considered evil?](http://stackoverflow.com/questions/7026507/why-are-static-variables-considered-evil) if anyone posts an answer that uses static – sam Oct 26 '15 at 21:54
  • @sam somebody answered using `static` as a *solution* – Luiggi Mendoza Oct 26 '15 at 21:56
  • @LuiggiMendoza Well, my effort to post link has paid off :) – sam Oct 26 '15 at 21:58

3 Answers3

0

The BAD and AVOID WHILE LEARNING solution: Move age and math local variables as static fields in the class.

The class will look like this:

public class TestScanner {
    static int age;
    static int math;
    //rest of your class...
    //in method grabInput
    static void grabInput() {
        //comment the variables
        //int age, math;
    }
}

The code above will work due to the usage of static fields. First understand what static means and be careful when using it.


You should ask yourself the following questions:

  • Should I have a method to display the fields of TestScanner inside the same class?
  • Should I create a new instance of TestScanner just to display the values of another instance of TestScanner?

In case you answer yes to both questions, then you can create a method that receives an instance of TestScanner and prints its contents. This is how your class will look like:

public class TestScanner {
    //Note: they're not static anymore (yay!)
    int age;
    int math;

    public static void main (String args[]) {
        TestScanner disInput = new TestScanner();
        TestScanner gInput = new TestScanner();
        gInput.grabInput();
        //note that now we need to pass the instance of TestScanner
        //in order to print its contents
        disInput.displayInput(gInput);
    }

    //method for display purposes
    void displayInput(TestScanner testScanner) {
        System.out.println("Scanner Input here: ");
        System.out.println("What is my age: ");
        System.out.println(testScanner.age);
        System.out.println("What is 2 +2: ");
        System.out.println(testScanner.math);
    }

    void grabInput() {
        Scanner stdin = new Scanner(System.in);
        System.out.println("What is my age: ");
        this.age = stdin.nextInt();
        System.out.println("What is 2 +2: ");
        this.math = stdin.nextInt();
    }
}

Now ask yourself: do I need all this? Is this a good design? Can I perform changes easily or will it take more time and effort to, for example, add a new variable, fill it and display it?

The main problem here is called cohesion. This is, the degree of functionalities within a class. As you can see, TestScanner itself has many responsibilities:

  • Store age and math
  • Read it from user input
  • Display the data to the user

A better approach will be to separate these functionalities in two classes:

  1. Person (or another name) that will store the data from user input. Based on the names of age and math fields, I thought a proper name of the class could be Person. This class will be in charge to store the data and provide it for different usage e.g. store user input and then use it for display purposes.
  2. A TestScanner class where you will test the usage of Scanner to read the data from user input and display data to user.

The design will look like this:

class Person {
    private int age;
    private int math;
    public Person(int age, int math) {
        this.age = age;
        this.math = math;
    }
    public int getAge() {
        return this.age;
    }
    public int getMath() {
        return this.math;
    }
    //setters avoided for this case
}

class TestScanner {
    Scanner scanner;
    public TestScanner(Scanner scanner) {
        this.scanner = scanner;
    }
    public Person grabInput() {
        System.out.println("What is my age: ");
        int age = stdin.nextInt();
        System.out.println("What is 2 +2: ");
        int math = stdin.nextInt();
        return new Person(age, math);
    }
    public void displayInput(Person person) {
        System.out.print("My age: ");
        System.out.println(person.getAge());
        System.out.print("My value of 2 +2: ");
        System.out.println(person.getMath());
    }
    public static void main(String[] args) {
        TestScanner testScanner = new TestScanner(new Scanner(System.in));
        Person person = testScanner.grabInput();
        testScanner.displayInput(person);
    }
}

Note: Links provided in questions are not for decoration purposes.

Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • If you make the variables static, then `grabInput()` also needs to be static. – Rainbolt Oct 26 '15 at 22:16
  • @Rainbolt that's not necessary. You can access to `static` fields from non-static methods. It's a bad practice but it works. I'm working on an edit. – Luiggi Mendoza Oct 26 '15 at 22:17
  • Sorry, I filled in the gaps (`//rest of your class...`) myself and decided it didn't work, but only because I implemented it wrong. I see how it works now. I'm against the suggestion to create a `Person` class because the OP doesn't appear to know about classes and instances yet. I wrote my answer under the assumption that he is still learning about methods and input/output, and tried to avoid creating instances of anything (except Scanner). – Rainbolt Oct 26 '15 at 22:22
0

You only need one scanner to get input, and you need to close the scanner when you are done:

int grabInput(String question)
{
    // Display a question to user
    System.out.println(question);

    // Read a response from user
    Scanner stdin = new Scanner(System.in);
    int input = stdin.nextInt();
    stdin.close();

    // Return the response
    return input;
}

You don't need any scanners at all to show output:

int displayOutput(String message, int response)
{
    System.out.println(message);
    System.out.println(response);
}

Here is what your main looks like with these changes:

public static void main (String args[])
{
    String ageQuestion = "What is my age?";
    int ageAnswer = grabInput(ageQuestion);

    String mathQuestion = "What is 2 + 2?";
    int mathAnswer = grabInput(mathQuestion);

    displayOutput(ageQuestion, ageAnswer);
    displayOutput(mathQuestion, mathAnswer);
}

The trick is to return the responses to main because you need access to them in another function, and to bury the Scanner logic in one function so that you don't have to worry about it anywhere else.

Rainbolt
  • 3,542
  • 1
  • 20
  • 44
-1

You can make a static variable in your TestScanner class, and every instance of your class will have access to that variable. Note that the variable will have the same value for each instance of your class.

import java.io.*;
import java.util.*;

class TestScanner
{
   public static Integer age;
   public static Integer math;
   public static void main (String args[])
   {
      TestScanner disInput = new TestScanner();
      TestScanner gInput = new TestScanner();
      gInput.grabInput();
      disInput.displayInput();


   }

   void displayInput()
   {
      System.out.println("Scanner Input here: ");
      System.out.println("What is my age: ");
      // How do I get age here
      System.out.pritln(age);
      System.out.println("What is 2 +2: ");
      // How do I get math here
      System.out.pritln(math);
   }

   void grabInput()
   {
     Scanner stdin = new Scanner(System.in);

     System.out.println("What is my age: ");
     age = stdin.nextInt();
     System.out.println("What is 2 +2: ");
     math = stdin.nextInt();

   }
}

You can take a look at what static variables are in java here.

Theo
  • 154
  • 1
  • 6