views:

533

answers:

4

First some code:

import java.util.*;
//...

class TicTacToe 
{
//...

public static void main (String[]arg) 
{ 

    Random Random = new Random() ; 
    toerunner () ; // this leads to a path of 
                   // methods that eventualy gets us to the rest of the code 
} 
//... 

public void CompTurn (int type, boolean debug) 
{ 
//...

        boolean done = true ; 
        int a = 0 ; 
        while (!done) 
        { 
            a = Random.nextInt(10) ;
            if (debug) { int i = 0 ; while (i<20) { System.out.print (a+", ") ; i++; }} 
            if (possibles[a]==1) done = true ; 
        } 
        this.board[a] = 2 ; 


}
//...

} //to close the class 

Here is the error message:

TicTacToe.java:85: non-static method nextInt(int) cannot be referenced from a static context
            a = Random.nextInt(10) ;
                      ^

What exactly went wrong? What does that error message "non static method cannot be referenced from a static context" mean?

+4  A: 

You are calling nextInt statically by using Random.nextInt.

Instead, create a variable, Random r = new Random(); and then call r.nextInt(10).

It would be definitely worth while to check out:

Update:

You really should replace this line,

Random Random = new Random(); 

with something like this,

Random r = new Random();

If you use variable names as class names you'll run into a boat load of problems. Also as a Java convention, use lowercase names for variables. That might help avoid some confusion.

Anthony Forloney
then i get a cannot find symbol error in regard to the r.
David
Did you initialize `r`? It can't just appear out of nowhere.
Anthony Forloney
yes i replaced both the second "Random" in main (so that it reads Random r = new Random();) and the "Random" comming before "nextInt"
David
Remove the `Random` declaration from `main` unless you necessarily need it, and just initialize `Random r = new Random();` inside `CompTurn`
Anthony Forloney
shouldn't i be able to create an instance of random inside main and then use it in other places?
David
I don't believe it is, once `main` runs it invokes `toerunner` which does whatever, so `toerunner` won't know that instance of random.
Anthony Forloney
@David your main method declares `r` as a local variable, so it won't be accessible from the `CompTurn()` instance method. In this case I'd say you should declare `r` as a static class field, e.g. `private static final Random r = new Random();`
Kevin K
isn't r an instance of Random though like an object? the syntax looks the same as creating an instance of an object.
David
Yes, it is, it is an object, but its scope is local to main, so it is not visible in other methods.
OscarRyz
A: 

You're trying to invoke an instance method on the class it self.

You should do:

    Random rand = new Random();
    int a = 0 ; 
    while (!done) { 
        int a = rand.nextInt(10) ; 
    ....

Instead

As I told you here stackoverflow.com/questions/2694470/whats-wrong...

OscarRyz
does it still work if i have the first line in mane? (see my comments on Anthony's answer).
David
In mane? Did you mean, in `main` ?? No, the random declared in `main` is local to that method. Once you get in a second method it is not reachable.
OscarRyz
A: 

In Java, static methods belong to the class rather than the instance. This means that you cannot call other instance methods from static methods unless they are called in an instance that you have initialized in that method.

Here's something you might want to do:

public class Foo
{
  public void fee()
  {
     //do stuff  
  }

  public static void main (String[]arg) 
  { 
     Foo foo = new Foo();
     foo.fee();
  } 
}

Notice that you are running an instance method from an instance that you've instantiated. You can't just call call a class instance method directly from a static method because there is no instance related to that static method.

artgon
A: 

Violating the Java naming conventions (variable names and method names start with lowercase, class names start with uppercase) is contributing to your confusion.

The variable Random is only "in scope" inside the main method. It's not accessible to any methods called by main. When you return from main, the variable disappears (it's part of the stack frame).

If you want all of the methods of your class to use the same Random instance, declare a member variable:

class MyObj {
  private final Random random = new Random();
  public void compTurn() {
    while (true) {
      int a = random.nextInt(10);
      if (possibles[a] == 1) 
        break;
    }
  }
}
erickson