Что такое "статичный"? - PullRequest
10 голосов
/ 27 мая 2009

Я начинаю программировать на Java.

public static void main(String[]args)

В книге сказано, что в этом случае я должен использовать static, но не ясно сказано, почему я должен или что это значит.

Не могли бы вы уточнить это?

Ответы [ 7 ]

23 голосов
/ 27 мая 2009

Понятие static связано с тем, является ли что-то частью класса или объекта (экземпляра).

В случае метода main, который объявлен как static, он говорит, что метод main является методом класса - методом, который является частью класса, а не частью объекта. Это означает, что другой класс может вызывать метод класса другого класса, ссылаясь на ClassName.method. Например, вызов метода run для MyClass будет выполняться следующим образом:

MyClass.main(new String[]{"parameter1", "parameter2"});

С другой стороны, метод или поле без модификатора static означает, что он является частью объекта (или также называется «экземпляром»), а не частью класса. На него ссылается имя конкретного объекта, которому принадлежит метод или поле, а не имя класса:

MyClass c1 = new MyClass();
c1.getInfo()     // "getInfo" is an instance method of the object "c1"

Поскольку каждый экземпляр может иметь разные значения, значения метода или поля с одинаковым именем в разных объектах не обязательно должны быть одинаковыми:

MyClass c1 = getAnotherInstance();
MyClass c2 = getAnotherInstance();

c1.value     // The field "value" for "c1" contains 10.
c2.value     // The field "value" for "c2" contains 12.
             // Because "c1" and "c2" are different instances, and 
             // "value" is an instance field, they can contain different
             // values.

Объединение двух понятий переменных экземпляра и класса. Допустим, мы объявляем новый класс, который содержит переменные и методы экземпляра и класса:

class AnotherClass {
    private int instanceVariable;
    private static int classVariable = 42;

    public int getInstanceVariable() {
        return instanceVariable;
    }

    public static int getClassVariable() {
        return classVariable;
    }

    public AnotherClass(int i) {
        instanceVariable = i;
    }
}

Приведенный выше класс имеет переменную экземпляра instanceVariable и переменную класса classVariable, которая объявлена ​​с модификатором static. Аналогично, есть метод экземпляра и класса для получения значений.

Конструктор для экземпляра принимает значение для присвоения переменной экземпляра в качестве аргумента. Переменная класса инициализируется как 42 и никогда не изменяется.

Давайте на самом деле воспользуемся приведенным выше классом и посмотрим, что произойдет:

AnotherClass ac1 = new AnotherClass(10);

ac1.getInstanceVariable();             // Returns "10"
AnotherClass.getClassVariable();       // Returns "42"

Обратите внимание на различные способы вызова методов класса и экземпляра. То, как они ссылаются на класс по имени AnotherClass или экземпляр по имени ac1. Давайте пойдем дальше и посмотрим на поведенческие различия методов:

AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);

ac1.getInstanceVariable();             // Returns "10"
AnotherClass.getClassVariable();       // Returns "42"
ac2.getInstanceVariable();             // Returns "20"
AnotherClass.getClassVariable();       // Returns "42"

Как видно, переменная экземпляра - это переменная, которая содержится в объекте (или "экземпляре"), поэтому уникальна для этого конкретного экземпляра, который в этом примере является объектами, на которые ссылаются ac1 и ac2 .

С другой стороны, переменная класса уникальна только для всего этого класса. Чтобы еще лучше разобраться в этом, давайте добавим новый метод к AnotherClass:

public int getClassVariableFromInstance() {
    return classVariable;
}

Затем выполните следующее:

AnotherClass ac1 = new AnotherClass(10);
AnotherClass ac2 = new AnotherClass(20);

ac1.getInstanceVariable();             // Returns "10"
ac1.getClassVariableFromInstance();    // Returns "42"
ac2.getInstanceVariable();             // Returns "20"
ac2.getClassVariableFromInstance();    // Returns "42"

Хотя getClassVariableFromInstance является методом экземпляра, что можно увидеть, вызвав ссылку на экземпляры ac1 и ac2, они оба возвращают одно и то же значение 42. Это связано с тем, что в обоих методах экземпляра они ссылаются на метод класса classVariable, который является уникальным для класса, а не на экземпляр - для класса AnotherClass имеется только одна копия classVariable.

Я надеюсь, что кое-что проясняет, для чего используется модификатор static.

Учебные руководства по Java от Sun содержат раздел Общие сведения об экземплярах и членах класса , в котором также рассматриваются два типа переменных и методов.

11 голосов
/ 27 мая 2009

Пожалуйста, смотрите хорошее описание на Википедии

Например, обратите внимание, как на уроке математики можно говорить такие вещи, как

Math.Abs(x);

без необходимости говорить

Math m = new Math();

Это статические методы, так как вам не нужен экземпляр. Методы экземпляра - это те методы, которые требуют, чтобы у вас был экземпляр класса.

Employee e = new Employee();
e.Terminate();
2 голосов
/ 27 мая 2009

Статический метод - это метод, который применяется ко всему классу, а не к какому-либо конкретному члену. .goExtinct () будет методом всей утки, а не какой-то конкретной утки. Функция main является общедоступной и статической, поскольку она должна быть всегда доступна и не должна входить в какой-либо конкретный класс.

1 голос
/ 27 мая 2009

В этом конкретном случае основной метод должен быть статическим, поскольку JVM начнет загружать классы и создавать объекты. Когда вы запускаете Java-программу, JVM будет искать определение переданного ей класса и загружать его. Таким образом, Java MyClass приведет к загрузке определения класса MyClass.

По определению Java-программа начнет выполняться в методе main () класса, который был передан в JVM в качестве класса для начальной загрузки. На данный момент не было создано ни одного экземпляра (объекта) типа MyClass, поэтому основной метод должен быть статическим, чтобы разрешить начало выполнения вашей программы.

Если вы хотите увидеть, какие классы загружаются во время выполнения Java-программы, вы можете использовать параметр командной строки -verbose: class.

1 голос
/ 27 мая 2009

Обычно для вызова методов у вас должен быть объект, экземпляр класса, по крайней мере по двум причинам:

  1. Это зависит от объекта, который класс реализует вызываемый метод. Например, если у вас есть экземпляр подкласса, вместо этого будет вызван метод в подклассе, даже если код, который вызывает метод, является тем же.
  2. Объекты обычно имеют внутреннее состояние (поля), на которое могут ссылаться методы. Это не работает, если нет экземпляра объекта.

Вы создаете экземпляры объектов, вызывая конструктор класса:

MyObject a = new MyObject();

Статические методы - это методы, которые не привязаны к экземплярам объекта. Их можно вызвать, просто назвав класс. В результате этого они

  1. нельзя динамически отправить подклассам (вот почему вы получаете предупреждение при попытке вызвать его для экземпляров объекта , что просто сбивает с толку синтаксис)
  2. они не могут ссылаться на состояние экземпляра (нестатические поля и другие нестатические методы).

Многие люди считают статические методы плохим шаблоном проектирования и советуют не использовать их (за исключением public static void main). Найдите альтернативный шаблон экземпляра.

0 голосов
/ 10 июня 2014

Будут времена, когда вы захотите определить члена класса, который будет использоваться независимо от любого объекта этого класса. Обычно доступ к члену класса возможен только в сочетании с объектом его класса. Тем не менее, можно создать элемент, который может использоваться сам по себе, без ссылки на конкретный экземпляр. Чтобы создать такого члена, предшествуйте его объявлению с ключевым словом static. Когда член объявляется статическим, к нему можно получить доступ до создания каких-либо объектов его класса и без ссылки на какой-либо объект. Вы можете объявить как методы, так и переменные как статические. Наиболее распространенным примером статического члена является main (). main () объявлен как static потому что он должен быть вызван, прежде чем какие-либо объекты существуют. Статические члены двух типов: статические поля и статические методы:

Static field:

Поле, объявленное с ключевым словом static, например:

private static int ballCount:

Позиция статического ключевого слова взаимозаменяема с позициями ключевых слов видимости (частных и общедоступных, а также защищенных). В результате также работает следующее утверждение:

static private int ballCount;

Как правило, большинство программистов ставят ключевое слово видимости на первое место.

Значение статического поля одинаково во всех экземплярах класса. Другими словами, если у класса есть статическое поле с именем CompanyName, все объекты, созданные из класса, будут иметь одинаковое значение для CompanyName.

Статические поля создаются и инициализируются при первой загрузке класса. Это происходит, когда к статическому члену класса обращаются или когда создается экземпляр класса, в зависимости от того, что наступит раньше.

Static method: 

Метод, объявленный с ключевым словом static. Как и статические поля, статические методы связаны с самим классом, а не с каким-либо конкретным объектом, созданным из класса. В результате вам не нужно создавать объект из класса, прежде чем вы сможете использовать статические методы, определенные классом.

Самый известный статический метод - это main, который вызывается средой исполнения Java для запуска приложения. Основной метод должен быть статическим, что означает, что приложения по умолчанию выполняются в статическом контексте.

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

0 голосов
/ 27 мая 2009

В любом объектно-ориентированном языке программирования, таком как Java или C ++, вы создаете классы, которые на самом базовом уровне похожи на BluePrints здания. Вы можете посмотреть на проект и определить, как различные компоненты связаны, но вы не можете фактически жить в нем. То же самое с классами и объектами. Классы - это план, и вы создаете экземпляр класса, который называется Object. Для одного и того же плана у вас может быть несколько зданий, таким же образом для одного класса вы можете иметь несколько объектов. Объект является экземпляром класса. Каждый метод в классе может быть вызван для Object или экземпляра класса, тогда как для вызова статических методов экземпляр вам фактически не нужен, вы можете напрямую вызвать ClassName.method () без фактического создания экземпляра класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...