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

Я очень запутался между двумя терминами. Я проверил stackoverflow, и есть аналогичный вопрос для C++, но не для java.

Может кто-нибудь объяснить разницу между двумя терминами для java?


person Alan2    schedule 30.07.2012    source источник
comment
Объявление — это минимум, необходимый для того, чтобы другой код мог вызывать его или ссылаться на него. Когда вы компилируете другой код, это минимум, который вам нужен. Определение требуется для того, чтобы что-то делать, его нужно скомпилировать только один раз (не один раз для каждого вызывающего объекта).   -  person Peter Lawrey    schedule 30.07.2012
comment
запоминается через: de-finite, fin = конец, закончить; de-clare, clarus = ясно, чтобы было ясно. Декларация ясно указывает на существование, тип и имя. Определение — это настоящий рабочий код, после которого можно заканчивать говорить о нем. Они используются независимо от языка, поэтому ваш вопрос означает, что Java использует эти общие концепции.   -  person n611x007    schedule 20.03.2014


Ответы (7)


Концептуальная разница проста:

  • Декларация: вы декларируете существование чего-либо, например класса, функции или переменной. Вы ничего не говорите о том, как выглядит этот класс или функция, вы просто говорите, что он существует.

  • Определение: вы определяете, как что-то реализовано, например, класс, функция или переменная, т. е. вы говорите что это на самом деле.

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

  • Классы: Java не разделяет объявления и определения, как это делает C/C++ (в файлах заголовков и cpp). Вы определяете их в том месте, где вы их объявляете.

  • Функции. Когда вы пишете интерфейс (или абстрактный класс), вы можете сказать, что объявляете функцию, не определяя ее. Однако обычные функции всегда определяются прямо там, где они объявлены. См. тело функции как ее определение, если хотите.

  • Переменные: объявление переменной может выглядеть следующим образом:

    int x;
    

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

Вот примерное описание того, как я использую эти термины:

abstract class SomeClass {                // class decl.
                                          //                           \
    int x;                                // variable decl.            |
                                          //                           |
    public abstract void someMethod();    // function decl.            |
                                          //                           |
    public int someOtherMethod() {        // function decl.            |
                                          //                           | class
        if (Math.random() > .5)           // \                         | def.
            return x;                     //  |  function definition   |
        else                              //  |                        |
            return -x;                    // /                         |
                                          //                           |
    }                                     //                           |
}                                         //                          /
person aioobe    schedule 30.07.2012
comment
К сожалению, это не поддерживается JLS. Согласно JLS, объявление класса ВКЛЮЧАЕТ тело класса. И то же самое относится к методам и конструкторам. - person Stephen C; 30.07.2012
comment
Верно. С формальной точки зрения я с вами полностью согласен (кроме случая абстрактных/интерфейсных методов). - person aioobe; 30.07.2012
comment
Я считаю, что это также относится к javascript, верно? Возможно, следует добавить тег JS. - person Griffin; 19.07.2013
comment
Судя по идентификаторам в коде javac, объявления классов кажутся синонимами определения класса. Рассмотрим, например, public void visitClassDef(JCClassDecl tree). - person aioobe; 07.01.2014
comment
@Гриффин - Плохая идея. Вопрос конкретно о Java. - person Stephen C; 18.06.2020

Спецификация языка Java определяет и широко использует объявление термина, но не использует определение, кроме как обычное английское слово.

Мое доказательство состоит в том, что объявление термина появляется несколько раз в таблице содержания JLS и в указателе. Напротив, определение слова не появляется ни в том, ни в другом.

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

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


Ответы, в которых говорится, что определение относится к точке, в которой инициализируется переменная, конкретно не поддерживаются... в контексте Java. В Java инициализация переменной происходит либо в момент объявления, либо при более позднем присвоении. В последнем случае специальный термин не используется... или не требуется... кроме присваивания и/или инициализации. Нет определенной точки, в которой память выделяется для переменной. Действительно, есть вероятность, что место для самой переменной будет выделено до объявления.


Причина, по которой термин определения не используется в Java в спецификации JLS, заключается в том, что он не нужен.

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

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

C и C++ обрабатывают эти вещи по-разному, и, следовательно, do нуждаются в разных терминах объявления и определения в своих технических описаниях. Мое мнение об определениях Sun Glossary заключается в том, что они ориентированы на C/C++.

person Stephen C    schedule 30.07.2012

Из определений Sun глоссария:

декларация. Оператор, который устанавливает идентификатор и связывает с ним атрибуты, не обязательно резервируя его место для хранения (для данных) или предоставляя реализацию (для методов).

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

Вот как я читаю глоссарий Sun:

List i;              // declaration - variable on the stack  
i = new ArrayList(); // definition - gives variable a reference
person Jainendra    schedule 30.07.2012
comment
1) JLS НЕ использует определение термина для описания второго оператора. Синтаксически это присваивание. Семантически это описывается как инициализация переменной. 2) Второй оператор не является объявлением, поэтому он не может быть определением... definition: Объявление, которое.... 3) Ссылка битая... - person Stephen C; 07.04.2013
comment
Я предложил правку, чтобы исправить ссылку. Вопрос и ответ ничего не говорят о JLS. - person Matthew Read; 07.08.2019

<сильный>1. Декларация означает создание primitive or Object reference variable, но без присваивания значения или объекта соответственно..

например:

          int x;   // declaration of x of type int

          Cat myCat;  //  declaration of myCat an Object of type Cat

<сильный>2. Определение — это когда мы присваиваем им значения или объекты.

         int x = 5;

         Cat myCat = new Cat();

3. В случае метода это так...

public abstract void go();       // Method Declaration (Abstract method)

   public void go(){               // Method Defination

            // Your code      

    }
person Kumar Vivek Mitra    schedule 30.07.2012
comment
Эта терминология НЕ поддерживается JLS. - person Stephen C; 30.07.2012
comment
@Kumar Vivek Mitra - если определение равно int x = 5, тогда в чем разница между определением и инициализацией? - person khan; 30.07.2012
comment
@SSK Инициализация - это определение и наоборот ..... ваш запрос кажется скорее сложной задачей, чем прояснением ваших сомнений ... так что в следующий раз добавьте, пожалуйста - person Kumar Vivek Mitra; 30.07.2012
comment
Ага... посмотрите серию Head First Java Кэти Сьерры и Берта Бейтса. - person Kumar Vivek Mitra; 30.07.2012

Я думаю, что могу лучше объяснить этот вопрос примерно так:

Подумайте о следующем сценарии:

В вашей фирме появилась новая вакансия инженера-программиста. Это означает, что человек, которого вы выберете для заполнения этой должности, будет инженером-программистом (вы не можете выбрать на эту должность специалиста по маркетингу). Таким образом, создание этого поста похоже на объявление.

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

Так сказать

SoftwareEngineer se;

означает декларацию;

а также

class SoftwareEngineer {

// define role and responsibilities
}

означает определение. Надеюсь, это поможет вам.

person me_digvijay    schedule 30.07.2012

Java язык определяет только объявление термина, а не определение.

Декларация:

class A{}// class declaration

String str;// variable declaration
person Mohammod Hossain    schedule 30.07.2012

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

         or

         1. Declaration means creating a primitive or Object reference variable, 
         but with no assignment of value or object respectively..

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

        or

         Defination is when we assign values or Object to them.

**Ex:** 
List i;              // declaration - variable on the stack  
i = new ArrayList(); // definition - gives variable a reference
person shraddha patel    schedule 16.05.2017