Javaでの宣言と定義の違いは何ですか?


81

私は2つの用語の間で非常に混乱しています。私はstackoverflowをチェックしましたが、C ++にも同様の質問がありますが、Javaにはありません。

誰かがJavaの2つの用語の違いを説明できますか?


2
宣言は、他のコードがそれを呼び出したり参照したりできるようにするために最低限必要なものです。他のコードをコンパイルする場合、これは必要最小限です。何かを行うには定義が必要です。コンパイルする必要があるのは1回だけです(呼び出し元ごとに1回ではありません)
Peter Lawrey 2012

1
記憶に残る方法:de-finite、fin = end、 "終了する"; de-clare、clarus = clear、「明確にする」。宣言は、存在、タイプ、および名前を明確にします。定義は「実際の作業」コードであり、その後「それについて話し終える」ことができます。それらは言語に依存しないように使用されているので、あなたの質問は、Javaがこれらの一般的な概念をどのように使用しているかを意味します。
n611x007 2014年

回答:


99

概念の違いは単純です。

  • 宣言:クラス、関数、変数など、何かが存在することを宣言しています。そのクラスまたは関数がどのように見えるかについては何も言わず、単に存在すると言うだけです。

  • 定義:クラス、関数、変数など、何かがどのように実装されるかを定義します。つまり、実際にであるを言います。

Javaでは、この2つにほとんど違いはなく、正式には、宣言には識別子だけでなくその定義も含まれます。これが私が個人的に用語を詳細に解釈する方法です:

  • クラス:Javaは、C / C ++のように(ヘッダーファイルとcppファイルで)宣言と定義を実際に分離しません。宣言した時点で定義します。

  • 関数:インターフェース(または抽象クラス)を作成しているときは、関数を定義せずに宣言していると言えます。ただし、通常の関数は、宣言された場所で常に正しく定義されます。必要に応じて、関数の本体をその定義として参照してください。

  • 変数:変数宣言は次のようになります。

    int x;
    

    (変数xが存在し、型を持っていることを宣言していますint)ローカル変数またはメンバーフィールドの場合。Javaでは、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によると、クラス宣言にはクラスの本体が含まれます。そして、同じことがメソッドとコンストラクターにも当てはまります。
スティーブンC

正しい。正式な観点から、私はあなたに完全に同意します(抽象/インターフェースメソッドの場合を除く)。
aioobe 2012

これはJavaScriptにも当てはまると思いますよね?たぶんJSタグを追加する必要があります。
グリフィン

のコードの識別子によるとjavac、クラス宣言はクラス定義と同義のようです。たとえばを考えてみましょうpublic void visitClassDef(JCClassDecl tree)
aioobe 2014年

@ Griffin-悪い考え。質問は特にJavaについてです。
スティーブン

28

Java言語仕様では、「宣言」という用語を広範に指定して使用していますが、通常の英語の単語以外では「定義」を使用していません。

私の証拠では、「宣言」という用語はJLSの目次と索引に何度も表示されますが、「定義」という単語はどちらにも表示されません。

したがって、Javaのコンテキストで「定義」という単語を使用している人を見ると、その人は技術的でない意味でそれを使用しているか、用語がずさんです。

後者の場合、それらは専門用語「宣言」と同じ意味である場合もあれば、別の意味である場合もあります。そして、彼らが何か他のものを意味するなら、あなたは彼らに彼らが何を意味するのか尋ねる必要があります。彼らがそれを定義した場合...十分に公平ですが、それは標準的な用語ではありません。


「定義」は変数が初期化されるポイントを指すと述べている回答は、Javaのコンテキストでは特にサポートされていません。Javaでは、変数の初期化は、宣言の時点で、または後の割り当てで行われます。後者の場合、割り当てや初期化を除いて、特別な用語は使用されません...または必要ありません...。変数にストレージが割り当てられる特定のポイントはありません。実際、宣言に到達する前に、変数自体のスペースが割り当てられる可能性があります。


JLS仕様のJavaで「定義」という用語が使用されていない理由は、「定義」という用語が必要ないためです。

  • Javaではメンバーを任意の順序で宣言できるため、「前方宣言」は必要ありません。これが、2つの概念を区別する必要がある状況です。
  • Javaでは、変数に必要なスタックスペースはコンパイル時定数であるため、スタックオフセットの計算はコンパイル時に行われます。(Javaでは、配列はヒープオブジェクトへの参照であり、参照のみがスタックフレームに保持されることに注意してください。)
  • Javaがフィールドまたは変数の「初期化なしの定義」を処理する方法では、単一の「宣言」ポイントは必要ありません。変数の初期化が必要な場合は、ソースコードの複数のポイントで発生する可能性があります。

(Javaで宣言と定義を使用した可能性があるのは、抽象メソッドだけです。ただし、使用した場合は、一貫性を保つために、通常のメソッド宣言を定義として参照する必要がありました。混乱するでしょう。したがって、彼らは単に「abstract」サブケースを抽象メソッドの宣言と呼んでいます。)

CとC ++はこれらを異なる方法で処理するため、技術的な説明に明確な「宣言」と「定義」の用語必要です。「SunGlossary」の定義についての私の見解は、それらがC / C ++中心であるということです。


7

Sunの用語集の定義:

宣言: 識別子を確立し、属性をそれに関連付けるステートメント。必ずしもストレージを予約したり(データ用)、実装を提供したりする必要はありません(メソッド用)。

定義: ストレージを予約する(データ用)か、実装を提供する(メソッド用)宣言。

私がSunの用語集を読む方法は、次のようになります。

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

4
1)JLSは、2番目のステートメントを説明するために「定義」という用語を使用しません。構文的には、それは割り当てです。意味的には、変数を「初期化する」と表現されます。2)2番目のステートメントは宣言ではないため、定義にすることはできません... 「定義:宣言...」。3)リンクが壊れています...
Stephen C

リンクを修正するための編集を提案しました。質疑応答は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ではサポートされていません。
スティーブンC

1
@Kumar VivekMitra-定義が "int x = 5"の場合、定義と初期化の違いは何でしょうか。
カーン2012

@SSKの初期化は定義であり、その逆も同様です.....疑問を解消するのではなく、問い合わせが非常に難しいようです...次回は「お願いします」を追加してください
Kumar Vivek Mitra

うん...キャシーシエラとバートベイツによるヘッドファーストJavaシリーズを参照してください
Kumar Vivek Mitra 2012

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. メソッドの場合

宣言:メソッドのシグネチャを指定する

定義:メソッドの実装を指定する

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.