2008-11-14 3 views
171

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

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

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

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();   
} 

ответ

253

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

+3

«Поскольку вы еще не создали объект, нестатический метод еще не существует». - Большое спасибо. Я должен был подумать об этом. – DragonBorn 2008-11-14 18:46:14

+5

Метод сам по себе существует. Где-то в определении загруженного класса. Так что ответ неправильный :) – 2008-11-14 19:57:46

41

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

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

+0

«Нестатические методы относятся к экземплярам класса» - Ответ. Но почему это относится к экземпляру класса? Спасибо. – DragonBorn 2008-11-14 18:09:17

+9

@ZiG: потому что вы сказали это, не отметив его статичным – 2008-11-14 19:04:47

+1

Для начинающих разработчиков я создал пример, чтобы понять, что @ StevenA.Lowe упомянул выше. https://repl.it/repls/WavyNeighboringSpotteddolphin – supritshah1289 2017-12-13 15:14:40

1

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

Ex:

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

1

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

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

4

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

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

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

или

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

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

10

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

Статические методы, вероятно, должны быть скорее исключением, чем нормой. Особенно рано, если вы хотите узнать ООП. (Зачем начинать с исключения из правила?) Это очень контр-педагогическая Java, что «первой» вещью, которую вы должны изучить, является публикация static void main thing. (Несколько реальных приложений Java имеют свои собственные основные методы.)

2

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

16

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

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

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()); 
    } 
} 

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

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

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

0

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

10

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

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

instanceMethod(); 
this.instanceMethod(); 

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

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

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

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

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

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

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


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

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

2

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

0

Итак, вы просите о главной причине?

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

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

0

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

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

Смежные вопросы