Как исправить - 41: на нестатическую переменную нельзя ссылаться из статического контекста -> В чем причина этого?

Я пытаюсь написать этот код, чтобы получить первые простые числа initialCapacity, а затем распечатать их последовательно, используя java. Это не работает по двум причинам, во-первых, я получаю сообщение об ошибке

41: на нестатическую переменную listOfPrimeNumbers нельзя ссылаться из статического контекста.

когда я пытаюсь запустить программу, но даже когда я меняю переменную на статическую и запускаю программу, она выводит только «1». Таким образом, цикл while в конструкторе Primes повторяется только один раз, а затем останавливается, и я просто не могу найти там проблему, как бы я ни искал! Может ли кто-нибудь помочь мне, пожалуйста, даже если бы вы могли просто очень быстро взглянуть и сказать мне, что может быть не так, я был бы очень признателен.

Кроме того, как обстоят дела с нестатическими и статическими переменными и методами? Какова наилучшая практика при их использовании? Если бы кто-нибудь мог связать меня со страницей, описывающей это (я безрезультатно гуглил!), я бы с удовольствием прочитал :)

Большое спасибо всем вам !

import java.util.*;
public class Primes {
  private ArrayList<Integer> listOfPrimeNumbers;

  public static void main(String[] args) {
    ArrayList<Integer> listOfPrimeNumbers;
    Primes generator=new Primes(50);
    print();
  }

  public Primes( int initialCapacity) {
    listOfPrimeNumbers = new ArrayList<Integer>(initialCapacity);    
    int index=0;
    int counter=0;
    while (counter != initialCapacity  ) {
      if (isPrime(index)) {
        listOfPrimeNumbers.add(index);
        counter++;
        System.out.println(counter);
        index++;
      }
      else {
        index++;
      }
    }
  }
  public boolean isPrime(int candidateNo) {
    Iterator<Integer> iter = listOfPrimeNumbers.iterator( );
    //in here ! ?
    int i=2;
    while ( iter.hasNext( ) ) {
      int next = iter.next( );
      if (next%i==0 && i!=1) {
        return false;
      }
    }
    return true;
  }

  public static void print( ) {
    int n = listOfPrimeNumbers.size();
    for(int i = 0; i <= n ; i++)
      System.out.println( listOfPrimeNumbers.get( i ) );

  }
}

Теперь я отредактировал свой код, чтобы все стало статичным (имеется в виду, что у меня может быть несколько экземпляров?). Теперь у меня есть это, проблема в том, что он просто печатает первые 51 число, а затем получает переполнение стека, может ли кто-нибудь помочь? Спасибо :) :

import java.util.*;
public class Primes {
  private static ArrayList<Integer> listOfPrimeNumbers;

  public static void main(String[] args) {
    ArrayList<Integer> listOfPrimeNumbers;
    Primes generator=new Primes(50);
    print();
  }

  public Primes( int initialCapacity) {
    listOfPrimeNumbers = new ArrayList<Integer>(initialCapacity);    
    int index=2;
    int counter=0;
    while (counter != initialCapacity  ) {
      if (isPrime(index)) {
        listOfPrimeNumbers.add(index);
        counter++;
        System.out.println(counter);
        index++;
      }
      else {
        index++;
      }
    }
  }
  public boolean isPrime(int candidateNo) {
    Iterator<Integer> iter = listOfPrimeNumbers.iterator( );
    while ( iter.hasNext( ) ) {
      int next = iter.next( );
      if (next%candidateNo==0 && candidateNo!=1) {
        return false;
      }
    }
    return true;
  }

  public static void print( ) {
    int n = listOfPrimeNumbers.size();
    for(int i = 0; i <= n ; i++)
      System.out.println( listOfPrimeNumbers.get( i ) );

  }
}

person user476033    schedule 29.11.2010    source источник
comment
возможный дубликат нестатической переменной не может быть указан из статического контекста (java)   -  person Don Roby    schedule 30.11.2010


Ответы (3)


listOfPrimeNumbers является членом вашего класса, а это значит, что каждый экземпляр Primes имеет собственную копию listOfPrimeNumbers.

print — это статическая функция, что означает, что она не связана с экземпляром Primes, и поэтому у нее нет доступа ни к одной из существующих переменных listOfPrimeNumbers (по одной на экземпляр вашего класса).

Таким образом, listOfPrimeNumbers должен быть статичным (т.е. во всем мире существует только одна копия), иначе print не может быть статичным.

person EboMike    schedule 29.11.2010

Ваш код не работает, потому что вы даже не используете candidateNo в isPrime.

Что касается разницы между статическими вещами и нестатическими вещами, нестатические относятся к конкретному экземпляру, а статические относятся к классу.

Вы не можете обращаться к нестатическому объекту из статического метода (или другого статического контекста), не указав сначала, о каком экземпляре вы говорите. Это как если бы я сказал: «Какого цвета машины?» Ваш ответ, вероятно, будет что-то вроде «какая машина?».

person Laurence Gonsalves    schedule 29.11.2010
comment
Большое спасибо за ответ! Не могу поверить, что пропустил глупую проблему с методом isPrime. Я отредактировал свой пост, включив в него свой новый код, но он все еще вызывает у меня проблему. Вы видите что-нибудь, что я делаю неправильно? - person user476033; 30.11.2010
comment
Вы проверяете, делятся ли ваши известные простые числа на вашего кандидата. Вы хотите проверить, делится ли ваш кандидат на известное простое число. - person Laurence Gonsalves; 30.11.2010
comment
Кстати: вы можете заменить первые 3 строки isPrime на: for (int next : listOfPrimeNumbers) { -- короче и легче читать. - person Laurence Gonsalves; 30.11.2010
comment
Конечно ! Благодарю вас ! Теперь он печатает простые числа, я поменял переменные в операторе if... он делает это навсегда, но это явное улучшение! Большое спасибо ! :) - person user476033; 30.11.2010
comment
@ user476033, в будущем вам, вероятно, следует избегать вопросов, состоящих из двух частей. После того, как на оригинал был дан ответ, вероятно, было бы уместно опубликовать второй вопрос, относящийся к любой следующей проблеме, с которой вы столкнулись. Прочитав это (час спустя), трудно понять, как развивалась эта публикация. - person Tim Bender; 30.11.2010

Это то, что вам нужно, если вы хотите сделать конкретизированный (нестатический) вызов функции. Для остальной части ответа см. ответ ЭбоМайка.

Primes generator=new Primes(50);
generator.print();

  public void print( ) {
    int n = listOfPrimeNumbers.size();
    for(int i = 0; i <= n ; i++)
      System.out.println( listOfPrimeNumbers.get( i ) );

  }
person Gazler    schedule 29.11.2010