У чому різниця між декларацією та визначенням у Java?


81

Я дуже плутаюся між цими двома термінами. Я перевірив stackoverflow, і є подібне запитання для C ++, але не для Java.

Хтось може пояснити різницю між двома термінами для Java?


2
Декларація є мінімально необхідним, щоб інший код міг її викликати або посилатися на неї. Під час компіляції іншого коду це мінімум, що вам потрібно. Визначення потрібно для того, щоб щось робити, воно має бути скомпільоване лише один раз (не один раз на абонента)
Пітер Лорі

1
запам'ятовується за допомогою: де-кінцевий, fin = кінець, "закінчити"; de-clare, clarus = clear, "щоб це було зрозуміло". У декларації чітко видно існування, тип та назву. Визначення - це "справжній робочий" код, після якого ви можете "закінчити розмову про це". Вони використовуються мовно-агностичними, тому ваше запитання означає, що Java використовує ці загальні поняття.
n611x007,

Відповіді:


99

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

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

  • Визначення : Ви визначаєте, як щось реалізується, наприклад, клас, функція чи змінна, тобто ви говорите, що це насправді.

У 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;                    // /                         |
                                          //                           |
    }                                     //                           |
}                                         //                          /

На жаль, JLS не підтримує цього. Відповідно до JLS, декларація класу ВКЛЮЧАЄ тіло класу. І те саме стосується методів та конструкторів.
Stephen C

Правильно. З формальної точки зору, я повністю з вами згоден (крім випадку абстрактних / інтерфейсних методів).
aioobe

Я вважаю, що це стосується і javascript, так? Можливо, слід додати тег JS.
Гріффін

Згідно з ідентифікаторами в коді javac, оголошення класу, здається, є синонімом визначення класу. Розглянемо, наприклад public void visitClassDef(JCClassDecl tree).
aioobe

@Griffin - Погана ідея. Питання стосується саме Java.
Stephen C

28

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

Я свідчу про те, що термін "декларація" неодноразово трапляється у змісті та покажчику JLS, але слово "визначення" не зустрічається ні в одному.

Отже, коли ви бачите, що хтось вживає слово "визначення" в контексті Java, він або використовує його в нетехнічному сенсі, або недбало ставиться до своєї термінології.

В останньому випадку вони можуть означати те саме, що і технічний термін "декларація", або вони можуть означати щось інше. А якщо вони мають на увазі щось інше, то потрібно запитати їх, що вони означають. Якщо вони це визначили ... досить справедливо, але це не стандартна термінологія.


Відповіді, в яких зазначено, що "визначення" відноситься до точки, в якій ініціалізується змінна, спеціально не підтримуються ... в контексті Java. У Java ініціалізація змінної відбувається або в точці оголошення, або при подальшому призначенні. В останньому випадку спеціальний термін не використовується ... або необхідний ... крім призначення та / або ініціалізації. Немає визначеного пункту, в якому зберігання виділяється для змінної. Дійсно, є ймовірність того, що простір для самої змінної виділено до досягнення оголошення.


Причиною того, що термін "визначення" не використовується в Java у специфікації JLS, є те, що він не потрібен.

  • Оскільки Java дозволяє оголошувати учасників у будь-якому порядку, немає необхідності в "переадресації оголошень". Саме в цьому контексті необхідно розрізняти ці два поняття.
  • У Java простором стека, необхідним для змінної, є константа часу компіляції, тому обчислення зміщення стека відбуваються під час компіляції. (Пам'ятайте, що в Java масив - це посилання на об'єкт купи ... і в кадрі стека зберігається лише посилання.)
  • Те, як Java обробляє "визначення без ініціалізації" поля або змінної, не вимагає єдиної точки "оголошення". Якщо потрібна ініціалізація змінної, це може статися в кількох точках вихідного коду.

(Єдине місце в Java, де вони могли б використовувати декларацію проти визначення, - це абстрактні методи. За винятком того, що якби вони це зробили, вони мали б посилатися на звичайну декларацію методу як на визначення ... для узгодженості ... і що було б заплутано. Тому вони просто називають "абстрактний" підпункт декларацією абстрактного методу.)

C і C ++ по-різному обробляють ці речі, а отже , потребують чітких термінів "декларація" та "визначення" в їх технічних описах. Я вважаю, що визначення "Словника сонця" полягає в тому, що вони є C / C ++ -центричними.


7

З визначень словника Сонця :

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

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

Я читав словник Сонця так:

List i;              // declaration - variable on the stack  
i = new ArrayList(); // definition - gives variable a reference

4
1) JLS НЕ використовує термін "визначення" для опису другого твердження. Синтаксично це призначення. Семантично це описується як "ініціалізація" змінної. 2) Друге твердження не є декларацією, тому воно не може бути визначенням ... "визначення: Декларацією, яке ..." . 3) Посилання порушено ...
Стівен С

Я запропонував редагування, щоб виправити посилання. Питання та відповідь нічого не говорять про JLS.
Метью Прочитав

4

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      

    }

1
Ця термінологія НЕ підтримується JLS.
Stephen C

1
@Kumar Vivek Mitra - якщо визначення визначається як "int x = 5", то якою буде різниця між визначенням та ініціалізацією?
хан

@SSK Ініціалізація - це визначення і навпаки ..... Ваш запит здається більшим викликом, а не очищенням Ваших сумнівів ... тому наступного разу додайте "будь ласка"
Кумар Вівек Мітра

Так ... дивіться серію Head First Java Кеті Сьєрри та Берта Бейтса
Кумар Вівек Мітра

2

Я думаю, що я можу краще пояснити це питання приблизно таким чином:

Подумайте про такий сценарій:

У вашій фірмі є нова вакантна посада інженера-програміста. Це означає, що особа, яку ви обрали на цю посаду, буде інженером-програмістом ((ви не можете обрати маркетингового хлопця для цієї посади). Отже, створення цієї публікації схоже на декларацію.

Тепер, коли ви визначаєте, що людина, яка займає цю посаду, може / не може робити, які повноваження вона має, які його обмеження, тоді це називається визначенням.

Так кажу

SoftwareEngineer se;

означає Декларація;

і

class SoftwareEngineer {

// define role and responsibilities
}

означає визначення. Сподіваюся, це допоможе вам.


2

Java мова визначає лише термін декларація, а не використання визначення.

Декларація:

class A{}// class declaration

String str;// variable declaration

0

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

         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

-1
  1. Для об’єкта або примітиву

Декларація : Вказівка типу об’єкта або примітиву

Визначення : Вказівка значення об’єкта або примітиву

  1. Для методу

Декларація : Вказівка підпису методу

Визначення : Вказівка реалізації методу

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.