C++ 有哪些常见的 Java 陷阱/陷阱? 程序员?

发布于 2024-07-11 19:28:38 字数 169 浏览 11 评论 0原文

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

我对那些在 C++ 领域工作多年并且必须使用 Java 的工程师的意见特别感兴趣,但其他人的任何指点甚至书籍推荐都非常受欢迎。

As the question says, what are some common/major issues that C++ programmers face when switching to Java? I am looking for some broad topic names or examples and day to day adjustments that engineers had to make. I can then go and do an in-depth reading on this.

I am specifically interested in opinions of engineers who have worked in C++ for years and had to work with Java but any pointers from others or even book recommendations are more than welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

在巴黎塔顶看东京樱花 2024-07-18 19:28:39

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

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

第三,java中实际上有指针,只是没有指针算术。 在java中它们被称为引用。 不要以为你可以忽略事物所指向的地方,它会大吃一惊。

  • == 和 .equals 不相等。

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

My biggest hurdle crossing from C++ to Java was ditching procedural code. I was very used to tying all my objects together within procedures. Without procedural code in java, I made circular references everywhere. I had to learn how to call objects from objects without them being dependents of each other. It was the Biggest hurdle but the easiest to overcome.

Number 2 personal issue is documentation. JavaDoc is useful but to many java projects are under the misconception that all that is needed is the JavaDoc. I saw much better documentation in C++ projects. This may just be a personal preference for documentation outside of the code.

Number 3. There are in fact pointers in java, just no pointer arithmetic. In java they are called references. Don't think that you can ignore where things are pointing at, it will come back with a big bite.

  • == and .equals are not equal.

  • == will look at the pointer(reference) while .equals will look at the value that the reference is pointing at.

坚持沉默 2024-07-18 19:28:39

泛型(而不是模板),具体是这样的它们是使用类型擦除实现的。

Generics (instead of templates), specifically the way they were implemented using type erasure.

与风相奔跑 2024-07-18 19:28:39

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

Since you mention book recommendations, definitely read Effective Java, 2nd ed.—it addresses most of the pitfalls I've seen listed in the answers.

撕心裂肺的伤痛 2024-07-18 19:28:39

当人们想到复制构造函数时,意外创建了一个引用:

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?!?!?  */

Creating a reference by accident when one was thinking of a copy constructor:

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?!?!?  */
残月升风 2024-07-18 19:28:39
  • 没有多重继承,每个类都隐式派生自 java.lang.Object (它有许多您必须知道和理解的重要方法)
  • 您可以通过实现接口来实现某种多重继承
  • 除了“+”之外没有运算符重载(对于字符串),并且绝对没有您可以自己做的
  • 没有无符号数字类型,除了 char 之外,它不应该真正用作数字类型。 如果您必须处理无符号类型,则必须进行大量转换和屏蔽。
  • 字符串不是以 null 结尾的,而是基于 char 数组,因此是不可变的。 因此,通过在循环中附加 += 来构建长字符串的时间复杂度为 O(n^2),所以不要这样做; 请改用 StringBuilder。
  • No multiple inheritance, and every class implicitly derives from java.lang.Object (which has a number of important methods you definitely have to know and understand)
  • You can have a sort of multiple inheritance by implementing interfaces
  • No operator overloading except for '+' (for Strings), and definitely none you can do yourself
  • No unsigned numerical types, except char, which shouldn't really be used as a numerical type. If you have to deal with unsigned types, you have to do a lot of casting and masking.
  • Strings are not null-terminated, instead they are based on char arrays and as such are immutable. As a consequence of this, building a long String by appending with += in a loop is O(n^2), so don't do it; use a StringBuilder instead.
萌化 2024-07-18 19:28:39

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

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

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

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

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

Getting used to having a garbage collector. Not being able to rely on a destructor to clean up resources that the GC does not handle.

Everything is passed by value, because references are passed instead of objects.

No copy constructor, unless you have a need to clone. No assignment operator.

All methods are virtual by default, which is the opposite of C++.

Explicit language support for interfaces - pure virtual classes in C++.

七堇年 2024-07-18 19:28:39

这些细微的语法差异让我着迷。 缺乏析构函数。

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

It's all the little bitty syntax differences that got me. Lack of destructors.

On the other hand, being able to write a main for each class (immensely handy or testing) is real nice; after you get used to it, the structure and tricks available with jar files are real nice; the fact that the semantics are completely defined (eg, int is the same everywhere) is real nice.

烟酒忠诚 2024-07-18 19:28:39

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

My worst problem was keeping in mind the ownership of memory at all times. In C++, it's a necessary thing to do, and it creates some patterns in developer's mind that are hard to overcome. In Java, I can forget about it (to a very high degree, anyway), and this enables some algorithms and approaches that would be exceedingly awkward in C++.

你在我安 2024-07-18 19:28:39

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

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

但是:

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

There are no objects in Java, there are only references to objects. E.g :

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

But :

MyClass myClass = new MyClass();   // Now it is a valid java object reference.
小情绪 2024-07-18 19:28:39

我读过的关于 Java“陷阱”的最好的书是 Java Puzzlers: Traps, Pitfalls和极端情况。 它不是专门针对 C++ 开发人员,但其中充满了您需要注意的示例。

The best book of Java "gotchas" that I've read is Java Puzzlers: Traps, Pitfalls, and Corner Cases. It's not specifically aimed at C++ developers, but it is full of examples of things you want to look out for.

挽心 2024-07-18 19:28:39

将方法参数指定为final并不意味着你一开始认为它意味着什么,

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

因为java是按值传递的,它正在做你所要求的事情,只是不是很明显,除非你理解java如何传递引用的值而不是目的。

Specifying a method parameter as final doesn't mean what you at first think it means

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

because java is pass by value it is doing what you're asking, just not immediately obvious unless you understand how java passes the value of the reference rather than the object.

吃素的狼 2024-07-18 19:28:39

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

object1=object2

复制它更改引用的对象

Another notable one is the keyword final and const. Java defines the const as a reserved keyword but doesn't specify much of its usage. Also

object1=object2

doesn't copy the objects it changes the reference

狠疯拽 2024-07-18 19:28:39

所有方法都是虚拟的。

参数化类型(泛型)实际上并不创建特定于参数的代码(即 List 使用与 List相同的字节码; 编译器是如果您尝试在前者中放入 Integer ,唯一会抱怨的事情)。

Varargs 很容易。

All methods are virtual.

Parameterized types (generics) don't actually create code parameter-specific code (ie, List<String> uses the same bytecode as List<Object>; the compiler is the only thing that complains if you try to put an Integer in the former).

Varargs is easy.

绿光 2024-07-18 19:28:38
  • 在 C++ 中,您可以使用析构函数来清理文件描述符、数据库连接等。 简单的等效方法是使用终结器。 不。 曾经。

相反,请使用这种模式:

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

您最终会经常做类似的事情。

  • 如果您未指定访问修饰符,在 Java 中,默认情况下成员是包私有的,这与 C++ 中的成员是私有的不同。 Package-private 是一个烦人的访问级别,意味着它是私有的,但同一包中的任何内容也可以访问它(恕我直言,这是一个愚蠢的默认访问级别);
  • 没有堆栈/堆分离。 一切都是在堆上创建的(好吧,这并不完全正确,但我们会假装它是);
  • 没有引用传递;
  • 与函数指针等效的是匿名接口。
  • In C++ you'd use destructors to clean up file descriptors, database connections and the like. The naive equivalent is to use finalizers. Don't. Ever.

Instead use this pattern:

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

You'll end up doing stuff like that a lot.

  • If you specify no access modifer, in Java the members are package-private by default, unlike C++ in which they are private. Package-private is an annoying access level meaning it's private but anything in the same package can access it too (which is an idiotic default access level imho);
  • There is no stack/heap separation. Everything is created on the heap (well, that's not strictly true but we'll pretend it is);
  • There is no pass-by-reference;
  • The equivalent to function pointers is anonymous interfaces.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文