在我的日常工作中,我刚刚花了一些时间帮助一个C++的人通过JNI(Java Native Interface)获得足够的Java来使用一些Java库,然后将内存共享到他们主要C++应用程序中。以下是我注意到的一些关键事项:
- 如果没有 IDE,就无法管理玩具项目以外的任何内容。你应该做的第一件事是下载一个流行的Java IDE(Eclipse是一个不错的选择,但也有替代方案,包括Netbeans和IntelliJ)。不要试图尝试使用vi / emacs和javac / make进行管理。你将生活在一个山洞里,却没有意识到这一点。一旦你掌握了基本的IDE功能,你就会比没有IDE时多几十倍。
- 了解如何布局简单的项目结构和包。将有关于如何在 Eclipse 站点或其他地方执行此操作的简单演练。切勿将任何内容放入默认包中。
- Java有一个类型系统,由于历史/性能原因,引用类型和基元类型相对分开。
- Java的泛型与C++模板不同。阅读“类型擦除”。
- 您可能希望了解Java的GC是如何工作的。只需谷歌“标记和扫描” - 首先,你可以满足于最天真的心智模型,然后了解现代生产GC稍后将如何做到这一点的细节。
- 应立即了解集合 API 的核心。Map / HashMap,List / ArrayList和LinkedList和Set应该足以开始。
- 了解现代 Java 并发。Thread是一个汇编语言级别的原语,与java.util.concurrent中的一些很酷的东西相比。学习 ConcurrentHashMap、Atomic*、Lock、Condition、CountDownLatch、BlockingQueue 和 Executeors 的线程池。这里的好书是Brian Goetz和Doug Lea的书。
- 只要你想使用第三方库,就需要了解类路径的工作原理。这不是火箭科学,但它有点冗长。
如果你是一个低级C++的人,那么你可能会发现其中一些很有趣:
- 缺省情况下,Java 具有虚拟调度功能。Java 方法上的关键字 static 用于指示类方法。私有 Java 方法使用 invokespecial 调度,这是对正在使用的确切类型的调度。
- 至少在 Oracle VM 上,对象包含两个标头的机器字(标记字和类字)。标记词是 VM 使用的一堆标志 - 特别是用于线程同步。可以将类词视为指向 VM 的 Class 对象表示形式的指针(这是方法的 vtable 所在的位置)。类词后面是对象实例的成员字段。
- Java .class文件是一种中间语言,与 x86 目标代码并不真正相似。特别是还有很多更有用的工具可用于.class文件(包括JVM附带的javap反汇编器)。
- 符号表的 Java 等效项称为常量池。它是类型化的,并且其中包含大量信息 - 可以说比x86目标代码等效物更多。
- Java 虚拟方法调度包括在常量池中查找要调用的正确方法,然后将其转换为偏移量到 vtable 中。然后沿类层次结构向上走,直到在该 vtable 偏移处找到一个非 null 值。
- Java从解释开始,然后进行编译(无论如何,对于Oracle和其他一些VM)。根据需要逐个方法切换到编译模式。在进行基准测试和性能调整时,您需要确保在开始之前已经预热了系统,并且通常应该在开始时在方法级别进行分析。所做的优化可能非常激进/乐观(如果违反假设,则进行检查和回退) - 因此perf调整是一门艺术。
希望有一些有用的东西可以继续 - 请评论/询问后续问题。