В чем разница между объявлением переменной из основного метода и внутри основного метода?

Когда я читал книгу о Java, я увидел один пример, написанный так. И мне интересно, могу ли я объявить переменную вне основного метода? В чем разница между объявлением переменной снаружи и внутри основного метода? Что такое "статическая" роль здесь? Пожалуйста, кто-нибудь мне объяснит? Я новичок в java.

public class Printstuff {
      static int an_integer = 0;
        public static void main(String[] args) {
          int an_integer = 2;
          String[] some_strings = {"Shoes", "Suit", "Tie" };
          an_integer = an_integer - 1;
          some_strings[an_integer] = some_strings[an_integer] +"+++";
          for (int i = 0; i < some_strings.length; i++)
            System.out.println(some_strings[Printstuff.an_integer]);
        }
    }

С уважением.

Ответ 1

1) Внутри и снаружи:

Если вы объявите свой объект внутри метода, он будет виден только в этом методе. В принципе, если вы помещаете скобки вокруг него, это только видимо/доступно изнутри этих скобок.

Если вы объявляете свой объект вне метода (внутри класса), это зависит от модификатора доступа .
По умолчанию он отображается/доступен изнутри этого класса и всего пакета.

2) Статический

Статический означает, что этот Object/Variable принадлежит самому классу, а не его объектам.

Пример:   

public class Members {

  static int memberCount;

  public Members() {
     memberCount++;
  }
}

memberCount существует только один раз, независимо от количества объектов класса. (даже до создания любого объекта!)

Каждый раз, когда вы создаете новый объект Members, увеличивается memberCount. Теперь вы можете получить доступ к нему следующим образом: Members.memberCount

Ответ 2

Объявление переменной в основном методе сделает ее доступной только в основном. Объявление переменной снаружи сделает ее доступной для всех методов класса, включая основной метод.

Пример:

public class Foo {
   private String varOne = "Test";

   public void testOne() {
     System.out.println(varOne);
     System.out.println(varTwo); // Error, this variable is available in the testTwo method only
   }

   public void testTwo() {
     String varTwo = "Bar";
     System.out.println(varOne); // Will display "Test"
     System.out.println(varTwo); // Will display "Bar"
   }
}

Ответ 3

Я заинтригован, что никто не упоминал вопросы памяти. Много лет назад создание экземпляра в main() предназначало бы эту переменную для стека, и, тем не менее, экземпляр этой функции мог бы выделять переменную в кучу. В те времена системы имели очень малые стеки, поэтому не проверять эту деталь может привести к переполнению стека очень легко. Я не эксперт в области архитектуры памяти, хотя я хочу, чтобы кто-то мог внести вклад в эту тонкую деталь, применимую к текущей архитектуре/памяти SW.

Ответ 4

Существует разница в объеме. И вы должны объявить его статичным, потому что ваша основная функция статична, поэтому вы можете использовать только статические переменные. Переменная, объявляющая внутри основного метода, будет использоваться только внутри основного метода.

Теперь вы можете подумать, почему мне нужен основной метод как статический!!! Поскольку любое приложение в java будет запускаться из основного метода, поэтому его можно вызывать по имени класса без создания какого-либо объекта, поэтому мы определяем его как статический. Весь статический метод может вызывать с помощью ссылки на класс, без необходимости.

Ответ 5

Теперь разница в an_integer больше.

Пример, если у вас есть другой метод.

public class Printstuff {
      static int an_integer = 0;
        public static void main(String[] args) {
          int an_integer = 2;
          String[] some_strings = {"Shoes", "Suit", "Tie" };
          an_integer = an_integer - 1;
          some_strings[an_integer] = some_strings[an_integer] +"+++";
          for (int i = 0; i < some_strings.length; i++)
            System.out.println(some_strings[Printstuff.an_integer]);
        }

      public void anotherMethod(){
         an_integer++;
      }


    }

Как вы объявили

<default package> int an_integer=0;

Все кланы в одном пакете имеют доступ к этой переменной.

Ответ 6

То, что вы называете, - это область видимости переменной.

Переменные внутри методов доступны только внутри этого метода, т.е. an_integer внутри метода main нельзя ссылаться вне метода main. Переменные могут даже иметь более узкие области, например, внутри петель. Классическая итерирующая переменная цикла for доступна только внутри цикла, а затем и ее.

Переменные внешние методы называются полями. Это зависит от его модификатора доступа, где его можно увидеть. Private поля, например, доступны только внутри этого класса, поля public могут быть доступны из любого места (другие модификаторы доступа protected и ни один, который возвращается к умолчанию). В принципе, вы можете использовать поле внутри класса для доступа к его значению из каждого метода внутри этого класса, однако это может быть опасно, если несколько потоков обращаются к одному экземпляру класса, но это целая другая история.

Поле и локальная переменная могут иметь одно и то же имя, что может привести к путанице. Обычно я предпочитаю не делать этого или, может быть, лучше, всегда ссылаться на поля с помощью this accessor. Я не уверен, есть ли предпочтение локальных переменных в сравнении с полями с тем же именем, но я бы предположил, что локальные переменные имеют более высокий приоритет при определении того, какой из них имел в виду.

Теперь поля

Static означают, что эта переменная не принадлежит экземпляру класса, а самому классу. Static поля (и методы) могут быть прочитаны (или вызваны) без необходимости инициализировать первый класс. Примером может быть стандартное значение класса, или, может быть, метод factory (если его метод). Поля Static могут также пригодиться для констант вместе с модификатором final. Поле public final static является почти глобальной константой.