Java中的声明和定义有什么区别?

新手上路,请多包涵

我对这两个术语感到很困惑。我检查了 stackoverflow,C++ 也有类似的问题,但 java 没有。

有人可以解释这两个 java 术语之间的区别吗?

原文由 Alan2 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

概念上的区别很简单:

  • _声明_:您 声明 某物存在,例如类、函数或变量。你什么都不说那个类或函数 是什么 样子,你只是说它存在。

  • _定义_:您 定义 某物的实现方式,例如类、函数或变量,即您 说出 它实际上是什么。

在Java 中,两者区别不大,形式上来说,一个声明不仅包括标识符,还包括它的定义。以下是我个人对这些术语的详细解释:

  • :Java 并不真正像 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;                    // /                         |
                                          //                           |
    }                                     //                           |
}                                         //                          /

原文由 aioobe 发布,翻译遵循 CC BY-SA 4.0 许可协议

Java Language Specification 广泛指定和使用术语“declaration”,但它不使用“definition”,除非是一个普通的英语单词。

我的证据是术语“声明”在 JLS 目录 索引中多次出现。相比之下,“定义” 一词既没有出现 在目录也没有出现在索引中。

因此,当您看到有人在 Java 上下文中使用“定义”一词时,他们要么是在非技术意义上使用它,要么就是对术语草率。

在后一种情况下,它们 可能 与技术术语“声明”具有相同的含义,或者它们可能具有其他含义。如果他们有别的意思,你需要问他们是什么意思。如果他们已经定义了它……很公平,但这不是标准术语。


Java Language Specification 特别不支持 声明“定义”指的是变量初始化点的答案。在 Java 中,变量的初始化要么发生在声明时,要么发生在稍后的赋值中。在后一种情况下,除了赋值和/或初始化之外,没有使用或不需要特殊术语。没有为变量分配存储的指定点。实际上,很可能变量本身的空间是在到达声明 之前 分配的。


JLS 规范中的 Java 未使用“定义”术语的原因是不需要它。

  • 由于 Java 允许以任何顺序声明成员,因此不需要“前向声明”。这就是有必要区分这两个概念的上下文。
  • 在 Java 中,变量所需的堆栈空间是编译时常量,因此堆栈偏移量计算发生在编译时。 (请记住,在 Java 中,数组是对堆对象的引用……并且只有引用保存在堆栈帧中。)
  • Java 处理字段或变量的“没有初始化的定义”的方式不需要单个“声明”点。如果需要对变量进行初始化,它可能会在源代码中的多个位置发生。

(在 Java 中,他们可能使用声明与定义的唯一地方是在抽象方法中。除非他们这样做了,否则他们将不得不引用常规方法声明作为定义……为了一致性……而且会令人困惑。所以他们只是将“抽象”子案例称为抽象方法的声明。)

C 和 C++ 处理这些事情的方式不同,因此在它们的技术描述中 确实 需要不同的“声明”和“定义”术语。我对“Sun Glossary”定义的看法是它们以 C / C++ 为中心。

原文由 Stephen C 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题