0

UPDATE: I made some changes based on some answers I got and it worked. The correct code is-

public class Tsett {
        static HashSet<String> names=new HashSet<String>();
        static String name="";
        public static void main(String[] args) {
        Scanner input=new Scanner(System.in);

        while(2>1){

    String s=input.next();
    char choice=s.charAt(0);

    switch(choice){
    case '1': addname(); break;
    case '2': removename(); break;
    case '3': displayname(); break;
    case '4': System.exit(0); break;
    default:System.out.println("Invalid Choice Entered.");
    }
        }



}
public static void addname(){
Scanner b=new Scanner(System.in);       
System.out.println("Enter a name to be added.");
name=b.next();
names.add(name);    
}
public static void removename(){
    Scanner b=new Scanner(System.in);   
    System.out.println("Enter a name to be remove.");
    name=b.next();
    names.remove(name);
}

public static void displayname(){
System.out.println("The names are as follows-");
for(String newname:names)
    System.out.println(newname);
    }

}

Using the keyword 'static' solved the problem.

I wrote the following code for my menu driven program on 'names'.

package tut4;

import java.util.HashSet;
import java.util.Scanner;

public class Tsett {

    HashSet<String> names = new HashSet<String>();

    public static void main(String[] args) {

        while (2 > 1) {

            Scanner input = new Scanner(System.in);
            String s = input.next();
            char choice = s.charAt(0);

            switch (choice) {
                case '1':
                    addname();
                    break;
                case '2':
                    removename();
                    break;
                case '3':
                    displayname();
                    break;
                case '4':
                    System.exit(0);
                    break;
                default:
                    System.out.println("Invalid Choice Entered.");
            }
        }

    }

    public static void addname() {
        String name = "";
        Scanner b = new Scanner(System.in);
        System.out.println("Enter a name to be added.");
        name = b.next();
        names.add(name);
    }

    public static void removename() {
        String name = "";
        Scanner b = new Scanner(System.in);
        System.out.println("Enter a name to be remove.");
        name = b.next();
        names.remove(name);
    }

    public static void displayname() {
        System.out.println("The names are as follows-");
        for (String newname : names) {
            System.out.println(newname);
        }
    }

}

The problem arising is that

cannot make static reference to non-static field "names"

in the addname(), removename(), displayname() functions.

Can anyone explain to me why this error is occurring and how to fix it?

yash10p
  • 33
  • 4
  • I would recommend trying out some of the links to very similar questions that can be found on the right hand side of this page. – Dawood ibn Kareem Jul 07 '14 at 05:32
  • check how you can call a static method from a another static method and normal method from a static method. its bit confusing but you SO a bit – vikeng21 Jul 07 '14 at 05:34
  • Ive posted this question so that someone could help me by suggesting the changes in my code. – yash10p Jul 07 '14 at 05:34

5 Answers5

4

Get use to not relying on static references. They have there place and uses, but to many people become reliant on them. You should also get use to using your main method to only initialise the program to such a state that you can hand off operation to the main/core class of the application.

Instead, I would get rid of you static modifiers on your methods and create an method that could "run" the core logic of your class.

In you main method, I would create an instance of the Tsett class and call this method. This way you gain access to the instance field names and methods

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
2

Change the declaration of names to

static HashSet<String> names = new HashSet<String>();

Because the methods are static, the variables that they reference must be static as well.
This is because a non-static variable must exist in a particular instance and can be different between instances, while static methods can not. If they are asked to reference a variable that is non-static, there is no way to know which instance of the class to use.

McLovin
  • 3,554
  • 1
  • 14
  • 15
  • 1
    It worked. And yeah I understand now why it was not working.I posted this question not to copy someone but I needed help with my code. Its like every other user is just waiting to downvote your question no matter what you do. Thanks for your help. – yash10p Jul 07 '14 at 05:39
  • I also had to declare the string name as static – yash10p Jul 07 '14 at 05:39
  • Declaring name as static? That doesn't seem right. Java doesn't allow static local variables. – McLovin Jul 07 '14 at 05:44
  • Check the updated code once, what I've done is that I've declared string name outside the functions to make it global. – yash10p Jul 07 '14 at 05:54
  • Code where everything is global and static gives me flashbacks to the 1970s. – Dawood ibn Kareem Jul 07 '14 at 06:19
2

You should create an instance of the class those methods are in.

String names;
Class class = new Class();  //Creating Instance of "Class" called "class".
names = class.addname(); //Access a method in "Class" using instance name "class" then method name and assign the value it returns to "names".

Than use names where ever you want to be displayed

  Switch(choice){
    case '1': names; break;
Ross
  • 57
  • 8
  • Can you explain to me what the above code will do. I simply can't understand it. – yash10p Jul 07 '14 at 05:49
  • Ok well your creating an instance of this class in the first line of code you need to use the class name you want to instantiate I used "Class". So now you can now access the methods in that class without having to make them static you can reference any methods in the class by referring to the name you called the instance in this case i named the instance "class" so i can now access the methods by using the 2nd line of code first creating a value that equals the value the method returnes i dont know what the method returns i just assumed it was a string you might have to change it. – Ross Jul 07 '14 at 05:58
  • Oh, I understand it now. Correct me if I'm wrong.In simple language, You have created an object named 'class' and then you can refer to it for invoking functions without declaring it as static. Am I right? – yash10p Jul 07 '14 at 06:02
  • Yep thats it. Then if those other methods are in that class you can just access them by using class.removename() & class.displayname() – Ross Jul 07 '14 at 06:06
  • This also means that I have to define these functions as member functions of the class. Then delcare an object and do the rest. Your method is clearly more efficient, thanks for your help. – yash10p Jul 07 '14 at 06:09
1

To fix your issue, you need to make the field 'names' static. The error you're getting is as a result of trying to call a non-static field in static context.

Try

private static HashSet<String> names = new HashSet<String>();

That will fix your problem.

Patrick W
  • 1,485
  • 4
  • 19
  • 27
0

Well, here are a few suggestions (you asked for them in your last comment..)

  1. Change while (2 > 1) to while(true).
  2. Put Scanner input = new Scanner(System.in); at class level.

  3. Put declarations for : String s = input.next(); char choice = s.charAt(0); outside the loop.

  4. No need for Scanner b = new Scanner(System.in); in all your methods.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • Check out my updated question and look at the changes I've made. – yash10p Jul 07 '14 at 05:48
  • @yash10p - Still, your code is *inefficient*. There are several changes that have to be made. – TheLostMind Jul 07 '14 at 05:56
  • The 'char choice=s.charAt(0)' statement is for the switch case and the 'Scanner b= new Scanner(System.in)' is for inputting the names. – yash10p Jul 07 '14 at 05:56
  • It is inefficient I know that, I've just moved to Java from C++. But it is not incorrect. Elaborate suggestions are welcome. – yash10p Jul 07 '14 at 05:58
  • The concepts would be the same in C++. You don't open the same stream multiple times:) – TheLostMind Jul 07 '14 at 06:00
  • I'm getting really confused. Please be more specific. – yash10p Jul 07 '14 at 06:05
  • One example : `while(2>1){ Scanner input=new Scanner(System.in);` You are relying hugely on the compiler to do smart optimizations for you. Else you will be creating a new `Scanner` object each time you iterate in the loop. – TheLostMind Jul 07 '14 at 06:08
  • Oh, I will put the Scanner statement outside the loop then. – yash10p Jul 07 '14 at 06:11
  • I was comparing that statement to 'cin>>' in C++. That's why I kept it inside the loop. But that's not the case. – yash10p Jul 07 '14 at 06:14
  • `cin>>` is similar to `scanner.next()` not `new Scanner(//inputStream)`. Nevertheless, we all learn these things slowly.. :P – TheLostMind Jul 07 '14 at 06:16