7

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

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

4

14 回答 14

15
  • 在 C++ 中,您将使用析构函数来清理文件描述符、数据库连接等。天真的等价物是使用终结器。不。曾经。

而是使用这种模式:

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

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

  • 如果您不指定访问修饰符,则在 Java 中,成员默认为包私有,不像 C++ 中它们是私有的。Package-private 是一个烦人的访问级别,这意味着它是私有的,但同一个包中的任何内容也可以访问它(恕我直言,这是一个愚蠢的默认访问级别);
  • 没有堆栈/堆分离。一切都是在堆上创建的(好吧,这并不完全正确,但我们会假装它是);
  • 没有传递引用;
  • 函数指针的等价物是匿名接口。
于 2009-01-11T22:36:42.047 回答
7

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

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

数字 3. 实际上在 java 中有指针,只是没有指针算术。在 java 中它们被称为引用。不要以为你可以忽略事物所指向的地方,它会大咬一口回来。

  • == 和 .equals 不相等。

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

于 2009-01-11T22:45:03.590 回答
5

泛型(而不是模板),特别是使用类型擦除实现它们的方式。

于 2009-01-11T22:39:48.843 回答
5

既然您提到书籍推荐,请务必阅读Effective Java,第 2 版。——它解决了我在答案中看到的大多数陷阱。

于 2009-01-11T23:22:45.137 回答
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?!?!?  */
于 2010-02-24T23:53:53.953 回答
4
  • 没有多重继承,每个类都隐含地派生自 java.lang.Object(它有许多你必须知道和理解的重要方法)
  • 您可以通过实现接口来获得一种多重继承
  • 除了 '+' (用于字符串)之外,没有运算符重载,而且绝对没有你可以自己做
  • 没有无符号数字类型,除了 char,它不应该真正用作数字类型。如果必须处理无符号类型,则必须进行大量转换和屏蔽。
  • 字符串不是以 null 结尾的,而是基于 char 数组,因此是不可变的。因此,通过在循环中附加 += 来构建一个长字符串是 O(n^2),所以不要这样做;改用 StringBuilder 。
于 2009-01-12T01:18:59.617 回答
3

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

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

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

默认情况下所有方法都是虚拟的,这与 C++ 正好相反。

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

于 2009-01-11T22:27:05.187 回答
2

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

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

于 2009-01-11T23:00:58.863 回答
2

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

于 2009-01-12T17:45:22.620 回答
2

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

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

但 :

MyClass myClass = new MyClass();   // Now it is a valid java object reference.
于 2010-02-25T00:09:09.603 回答
1

我读过的关于 Java“陷阱”的最好的书是Java Puzzlers: Traps, Pitfalls, and Corner Cases。它不是专门针对 C++ 开发人员的,但它充满了你想要注意的事情的例子。

于 2009-01-11T23:32:48.143 回答
0

所有方法都是虚拟的。

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

可变参数很容易。

于 2009-01-12T01:07:07.673 回答
0

将方法参数指定为 final 并不意味着您最初认为的含义

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

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

于 2010-02-25T00:41:40.470 回答
0

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

object1=object2

不复制对象它更改引用

于 2013-10-25T18:58:24.080 回答