【问题标题】:What are some common Java pitfalls/gotchas for C++ programmer?C++ 程序员有哪些常见的 Java 陷阱/陷阱?
【发布时间】:2009-01-11 22:22:35
【问题描述】:

正如问题所说,C++ 程序员在切换到 Java 时会面临哪些常见/主要问题?我正在寻找工程师必须进行的一些广泛的主题名称或示例以及日常调整。然后我可以去深入阅读这个。

我对在 C++ 中工作多年并不得不使用 Java 的工程师的意见特别感兴趣,但我们非常欢迎其他人的任何指点甚至书籍推荐。

【问题讨论】:

    标签: java c++ language-switching


    【解决方案1】:
    • 在 C++ 中,您可以使用析构函数来清理文件描述符、数据库连接等。天真的等价物是使用终结器。不。永远。

    改为使用这种模式:

    OutputStream os;
    try {
      os = ... 
      // do stuff
    } finally {
      try { os.close(); } catch (Exception e) { }
    }
    

    你最终会做很多这样的事情。

    • 如果您不指定访问修饰符,在 Java 中,成员默认为包私有,这与 C++ 中的成员是私有的不同。 Package-private 是一个令人讨厌的访问级别,这意味着它是私有的,但同一个包中的任何内容也可以访问它(恕我直言,这是一个愚蠢的默认访问级别);
    • 没有堆栈/堆分离。一切都是在堆上创建的(好吧,严格来说这不是真的,但我们会假装是的);
    • 没有传递引用;
    • 函数指针的等价物是匿名接口。

    【讨论】:

    【解决方案2】:

    我从 C++ 到 Java 的最大障碍是放弃过程代码。我非常习惯在程序中将我的所有对象捆绑在一起。没有 java 中的程序代码,我到处都做了循环引用。我必须学习如何从对象中调用对象,而不会使它们相互依赖。这是最大的障碍,但最容易克服。

    第二个个人问题是文档。 JavaDoc 很有用,但是对于许多 Java 项目来说,他们误以为所需要的只是 JavaDoc。我在 C++ 项目中看到了更好的文档。这可能只是个人对代码之外文档的偏好。

    第三个。其实java中有指针,只是没有指针算法。在 java 中,它们被称为 references。不要以为你可以忽略事物所指向的地方,它会大咬一口回来。

    • == 和 .equals 不相等。

    • == 将查看指针(引用),而 .equals 将查看引用指向的值。

    【讨论】:

    • 您能解释一下您可以在 C++ 中使用但在 Java 中不能使用的循环引用类型吗?
    • 我将进行编辑以澄清。我想说的是,当我第一次开始用 java 编码时,我开始循环引用,因为我无法按程序进行编码。至少我所知道的开发人员认为,循环引用是一种不好的形式。
    【解决方案3】:

    Generics(而不是模板),特别是使用type erasure 实现它们的方式。

    【讨论】:

      【解决方案4】:

      既然您提到了书籍推荐,请务必阅读Effective Java, 2nd ed.——它解决了我在答案中看到的大部分陷阱。

      【讨论】:

      • 第二个。这是一本很棒的小书,旨在回答您的问题(陷阱、陷阱和最佳实践)。
      【解决方案5】:

      在考虑复制构造函数时意外创建了一个引用:

      myClass me = new myClass();
      myClass somebodyElse = me; /* A reference, not a value copied into an independent instance! */
      somebodyElse.setPhoneNumber(5551234);
      /* Hey... how come my phone doesn't work anymore?!?!?  */
      

      【讨论】:

      • 我想 C 程序员是最有能力理解这一点的人之一,因为他们与指针和引用值有着密切的关系。
      【解决方案6】:
      • 没有多重继承,每个类都隐式派生自 java.lang.Object(它有许多您必须知道和理解的重要方法)
      • 您可以通过实现接口来实现某种多重继承
      • 没有运算符重载,除了 '+'(用于字符串),绝对没有你可以自己做的
      • 没有无符号数字类型,除了 char,它不应该真正用作数字类型。如果必须处理无符号类型,则必须进行大量转换和屏蔽。
      • 字符串不是以 null 结尾的,而是基于 char 数组,因此是不可变的。因此,通过在循环中附加 += 来构建一个长字符串是 O(n^2),所以不要这样做;请改用 StringBuilder。

      【讨论】:

      • 另外:没有为对象“传递值”的选项。
      【解决方案7】:

      习惯使用垃圾收集器。无法依赖析构函数来清理 GC 无法处理的资源。

      一切都是按值传递的,因为传递的是引用而不是对象。

      没有复制构造函数,除非你需要克隆。没有赋值运算符。

      所有方法默认都是虚的,这与C++相反。

      对接口的显式语言支持 - C++ 中的纯虚拟类。

      【讨论】:

        【解决方案8】:

        正是这些细微的语法差异吸引了我。缺乏析构函数。

        另一方面,能够为每个类(非常方便或测试)编写一个 main 是非常好的;习惯之后,jar 文件的结构和技巧真的很不错;语义是完全定义的(例如,int 在任何地方都是相同的)这一事实非常好。

        【讨论】:

          【解决方案9】:

          我最糟糕的问题是始终牢记内存的所有权。在 C++ 中,这是必须要做的事情,它在开发人员的脑海中创造了一些难以克服的模式。在 Java 中,我可以忘记它(在很大程度上,无论如何),这使得一些在 C++ 中非常尴尬的算法和方法成为可能。

          【讨论】:

            【解决方案10】:

            Java 中没有对象,只有对象的引用。例如:

            MyClass myClass;   // no object is created unlike C++.
            

            但是:

            MyClass myClass = new MyClass();   // Now it is a valid java object reference.
            

            【讨论】:

              【解决方案11】:

              我读过的最好的Java“陷阱”书是Java Puzzlers: Traps, Pitfalls, and Corner Cases。它并非专门针对 C++ 开发人员,但它充满了您需要注意的示例。

              【讨论】:

                【解决方案12】:

                将方法参数指定为 final 并不意味着你最初认为的意思

                private void doSomething(final MyObject myObj){
                   ...
                   myObj.setSomething("this will change the obj in the calling method too");
                   ...
                }
                

                因为 java 是按值传递的,所以它正在做您所要求的事情,除非您了解 java 如何传​​递引用而不是对象的值,否则不会立即显而易见。

                【讨论】:

                  【解决方案13】:

                  另一个值得注意的是关键字finalconst。 Java 将 const 定义为保留关键字,但没有详细说明它的用法。还有

                  object1=object2
                  

                  不复制它更改引用的对象

                  【讨论】:

                    【解决方案14】:

                    所有方法都是虚拟的。

                    参数化类型(泛型)实际上不会创建代码参数特定的代码(即List<String> 使用与List<Object>; 相同的字节码,如果您尝试将Integer 放入,编译器是唯一会抱怨的东西前者)。

                    可变参数很简单。

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-06-05
                      • 1970-01-01
                      • 2011-12-11
                      • 2012-06-30
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多