В чем причина "нестатического метода нельзя ссылаться из статического контекста"?

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

Вы можете сделать статический статический метод или сделать экземпляр этого класса для использования его свойств.

Почему? Я не прошу решения. Я был бы признателен, чтобы узнать, в чем причина этого. Самая главная причина!

private java.util.List<String> someMethod(){
    /* Some Code */
    return someList;            
}

public static void main(String[] strArgs){          
     // The following statement causes the error. You know why..
    java.util.List<String> someList = someMethod();         
}

Ответ 1

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

Ответ 2

Метод, который вы пытаетесь вызвать, - это метод уровня экземпляра; у вас нет экземпляра.

static относятся к классу, методы static относятся к экземплярам класса.

Ответ 3

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

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

public class Foo
{
    private String foo;
    public Foo(String foo){ this.foo = foo; }
    public getFoo(){ return this.foo; }

    public static void main(String[] args){
        System.out.println( getFoo() );
    }
}

Что может быть результатом запуска вышеуказанной программы?

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

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

Ответ 4

Я только что понял, я думаю, что люди не должны подвергаться концепции "статические" очень рано.

Статические методы, вероятно, должны быть скорее исключением, чем нормой. Особенно рано, если вы хотите узнать ООП. (Зачем начинать с исключения из правила?) Это очень контр-педагогическая Java, что "первая" вещь, которую вы должны изучить, - это общественная статическая недействительность. (В любом случае, некоторые реальные Java-приложения имеют свои собственные основные методы.)

Ответ 5

Я думаю, стоит отметить, что по правилам Java-языка компилятор Java вставляет эквивалент "this". когда он замечает, что вы обращаетесь к методам экземпляра или полям экземпляра без явного экземпляра. Конечно, компилятор знает, что он может делать это только из метода экземпляра, который имеет "эту" переменную, поскольку статические методы этого не делают.

Это означает, что когда вы находитесь в методе экземпляра, следующие эквиваленты:

instanceMethod();
this.instanceMethod();

и они также эквивалентны:

... = instanceField;
... = this.instanceField;

Компилятор эффективно вставляет "это". когда вы не поставляете конкретный экземпляр.

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

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

Механизм вызова статического метода проще, например вызов функции на языке, отличном от OOP.

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


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

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

Ответ 6

Ответы до сих пор описывают, почему, но вот что-то еще вы можете рассмотреть:

Вы можете вызвать метод из экземпляра класса, добавив вызов метода к его конструктору,

Object instance = new Constuctor().methodCall();

или

primitive name = new Constuctor().methodCall();

Это полезно, что вы только хотите использовать метод экземпляра класса один раз в рамках одной области. Если вы вызываете несколько методов из экземпляра класса в пределах одной области действия, определенно создайте ссылочный экземпляр.

Ответ 7

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

Ответ 8

Компилятор фактически добавляет аргумент нестационарным методам. Он добавляет this pointer/reference. This is also the reason why a static method can not use this, потому что нет объекта.

Ответ 9

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

Пример:

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

Ответ 10

Если метод не является статичным, он "сообщает" компилятору, что метод требует доступа к данным уровня экземпляра в классе (например, нестатическое поле). Эти данные не будут доступны, если только экземпляр класса не был создан. Поэтому компилятор выдает ошибку, если вы попытаетесь вызвать метод из статического метода. Если на самом деле метод НЕ ссылается на какой-либо нестатический член класса, сделайте метод static.

В Resharper, например, просто создавая нестатический метод, который НЕ ссылается на какой-либо статический член класса, генерирует предупреждающее сообщение "Этот метод может быть сделан статическим"

Ответ 11

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

Ответ 12

Итак, вы просите очень основную причину?

Хорошо, поскольку вы разрабатываете в Java, компилятор генерирует объектный код, который может интерпретировать Java Virtual Machine. JVM в любом случае представляет собой двоичную программу, которая запускается на языке машины (вероятно, версия JVM, специфичная для вашей операционной системы и оборудования, была ранее скомпилирована другим языком программирования, например C, чтобы получить машинный код, который может работать в вашем процессоре). В конце любой код переводится в машинный код. Таким образом, создание объекта (экземпляр класса) эквивалентно резервированию пространства памяти (регистры памяти, которые будут обрабатываться процессором, когда планировщик ЦП операционной системы помещает вашу программу в верхнюю часть очереди для ее выполнения) иметь место для хранения данных, которое может читать и записывать данные. Если у вас нет экземпляра класса (который происходит в статическом контексте), то у вас нет этого пространства памяти для чтения или записи данных. На самом деле, как и другие люди, данные не существуют (потому что с самого начала вы никогда не писали, и не зарезервировали пространство памяти для его хранения).

Извините за мой английский! Я латинский!

Ответ 13

Нестатический метод зависит от объекта. Он распознается программой после создания объекта.

Статические методы можно вызвать еще до создания объекта. Статические методы отлично подходят для выполнения сравнений или операций, которые не зависят от реальных объектов, с которыми вы планируете работать.