Effective-Java 第三版中文版 明智审慎地本地方法

66. 明智审慎地本地方法

Java 本地接口(JNI)允许 Java 程序调用本地方法,这些方法是用 C 或 C++ 等本地编程语言编写的。从历史上看,本地方法主要有三种用途。它们提供对特定于平台的设施(如注册中心)的访问。它们提供对现有本地代码库的访问,包括提供对遗留数据访问。最后,本地方法可以通过本地语言编写应用程序中注重性能的部分,以提高性能。

使用本地方法访问特定于平台的机制是合法的,但是很少有必要:随着 Java 平台的成熟,它提供了对许多以前只能在宿主平台中上找到的特性。例如,Java 9 中添加的流 API 提供了对 OS 流程的访问。在 Java 中没有等效库时,使用本地方法来使用本地库也是合法的。

为了提高性能,很少建议使用本地方法。 在早期版本(Java 3 之前),这通常是必要的,但是从那时起 JVM 变得更快了。对于大多数任务,现在可以在 Java 中获得类似的性能。例如,在版本 1.1 中添加了 java.math,BigInteger 是在一个用 C 编写的快速多精度运算库的基础上实现的。在当时,为了获得足够的性能这样做是必要的。在 Java 3 中,BigInteger 则完全用 Java 重写了,并且进行了性能调优,新的版本比原来的版本更快。

这个故事的一个可悲的结尾是,除了在 Java 8 中对大数进行更快的乘法运算之外,BigInteger 此后几乎没有发生什么变化。在此期间,对本地库的工作继续快速进行,尤其是 GNU 多精度算术库(GMP)。需要真正高性能多精度算法的 Java 程序员现在可以通过本地方法使用 GMP [Blum14]。

使用本地方法有严重的缺点。由于本地语言不安全(详见第 50 条),使用本地方法的应用程序不再能免受内存毁坏错误的影响。由于本地语言比 Java 更依赖于平台,因此使用本地方法的程序的可移植性较差。它们也更难调试。如果不小心,本地方法可能会降低性能,因为垃圾收集器无法自动跟踪本地内存使用情况(详见第 8 条),而且进出本地代码会产生相关的成本。最后,本地方法需要「粘合代码」,这很难阅读,而且编写起来很乏味。

总之,在使用本地方法之前要三思。一般很少需要使用它们来提高性能。如果必须使用本地方法来访问底层资源或本地库,请尽可能少地使用本地代码,并对其进行彻底的测试。本地代码中的一个错误就可以破坏整个应用程序。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
译者序 序 前言 致谢 第1章 引言 第2章 创建和销毁对象 第1条:考虑用静态工厂方法代替构造器 第2条:遇到多个构造器参数时要考虑用构建器 第3条:用私有构造器或者枚举类型强化Singleton属性 第4条:通过私有构造器强化不可实例化的能力 第5条:避免创建不必要的对象 第6条:消除过期的对象引用 第7条:避免使用终结方法 第3章 对于所有对象都通用的方法 第8条:覆盖equals时请遵守 通用约定 第9条:覆盖equals时总要覆盖hashCode 第10条:始终要覆盖toString 第11条:谨慎覆盖clone 第12条:考虑实现Comparable接口 第4章 类和接口 第13条:使类和成员的可访问性最小化 第14条:在公有类中使用访问方法而非公有域 第15条:使可变性最小化 第16条:复合优先于继承 第17条:要么为继承而设计,并提供文档说明,要么就禁止继承 第18条:接口优于抽象类 第19条:接口只用于定义类型 第20条:类层次优于标签类 第21条:用函数对象表示策略 第22条:优先考虑静态成员类 第5章 泛型 第23条:请不要在新代码中使用原生态类型 第24条:消除非受检警告 第25条:列表优先于数组 第26条:优先考虑泛型 第27条:优先考虑泛型方法 第28条:利用有限制通配符来提升API的灵活性 第29条:优先考虑类型安全的异构容器 第6章 枚举和注解 第30条:用enum代替int常量 第31条:用实例域代替序数 第32条:用EnumSet代替位域 第33条:用EnumMap代替序数索引 第34条:用接口模拟可伸缩的枚举 第35条:注解优先于命名模式 第36条:坚持使用Override注解 第37条:用标记接口定义类型 第7章 方法 第38条:检查参数的有效性 第39条:必要时进行保护性拷贝 第40条:谨慎设计方法签名 第41条:慎用重载 第42条:慎用可变参数 第43条:返回零长度的数组或者集合,而不是:null 第44条:为所有导出的API元素编写文档注释 第8章 通用程序设计 第45条:将局部变量的作用域最小化 第46条:for-each循环优先于传统的for循环 第47条:了解和使用类库 第48条:如果需要精确的答案,请避免使用float和double 第49条:基本类型优先于装箱基本类型 第50条:如果其他类型更适合,则尽量避免使用字符串 第51条:当心字符串连接的性能 第52条:通过接口引用对象 第53条:接口优先于反射机制 第54条:谨慎使用本地方法 第55条:谨慎进行优化 第56条:遵守普遍接受的命名惯例 第9章 异常 第57条:只针对异常的情况才使用异常 第58条:对可恢复的情况使用受检异常,对编程错误使用运行时异常 第59条:避免不必要使用受检的异常 第60条:优先使用标准的异常 第61条:抛出与抽象相对应的异常 第62条:每个方法抛出的异常都要有文档 第63条:在细节消息中包含能捕获失败的信息 第64条:努力使失败保持原子性 第65条:不要忽略异常 第10章 并发 第66条:同步访问共享的可变数据 第67条:避免过度同步 第68条:executor和task优先干线程 第69条:并发工具优先于wait和notify 第70条:线程安全性的文档化 第71条:慎用延迟初始化 第72条:不要依赖于线程调度器 第73条:避免使用线程组 第11章 序列化 第74条:谨慎实现Serializable接口 第75条:考虑使用自定义的序列化形式 第76条:保护性编写readObject方法 第77条:对于实例控制,枚举类型优先于readResolve 第78条:考虑用序列化代理代替序列化实例 附录 第1版与第2版条目对照 中英文术语对照 参考文献
effective java 中文第三版 pdf文件下载 目录 01. 考虑使用静态工厂方法替代构造方法.md 02. 当构造方法参数过多时使用builder模式.md 03. 使用私有构造方法或枚类实现Singleton属性.md 04. 使用私有构造方法执行非实例化.md 05. 使用依赖注入取代硬连接资源(hardwiring resources).md 06. 避免创建不必要的对象.md 07. 消除过期的对象引用.md 08. 避免使用Finalizer和Cleaner机制.md 09. 使用try-with-resources语句替代try-finally语句.md 10. 重写equals方法时遵守通用约定.md 11. 重写equals方法时同时也要重写hashcode方法.md 12. 始终重写 toString 方法.md 13. 谨慎重写 clone 方法.md 14. 考虑实现Comparable接口.md 15. 使类和成员的可访问性最小化.md 16. 在公共类中使用访问方法而不是公共属性.md 17. 最小化可变性.md 18. 组合优于继承.md 19. 如使用继承则设计,应当文档说明,否则不该使用.md 20. 接口优于抽象类.md 21. 为后代设计接口.md 22. 接口仅用来定义类型.md 23. 优先使用类层次而不是标签类.md 24. 优先考虑静态成员类.md 25. 将源文件限制为单个顶级类.md 26. 不要使用原始类型.md 27. 消除非检查警告.md 28. 列表优于数组.md 29. 优先考虑泛型.md 30. 优先使用泛型方法.md 31. 使用限定通配符来增加API的灵活性.md 32. 合理结合泛型和可变参数.md 33. 优先考虑类型安全的异构容器.md 34. 使用枚举类型替代整型常量.md 35. 使用实例属性替代序数.md 36. 使用EnumSet替代位属性.md 37. 使用EnumMap替代序数索引.md 38. 使用接口模拟可扩展的枚举.md 39. 注解优于命名模式.md 40. 始终使用Override注解.md 41. 使用标记接口定义类型.md 42. lambda表达式优于匿名类.md 43. 方法引用优于lambda表达式.md 44. 优先使用标准的函数式接口.md 45. 明智审慎使用Stream.md 46. 优先考虑流中无副作用的函数.md 47. 优先使用Collection而不是Stream来作为方法的返回类型.md 48. 谨慎使用流并行.md 49. 检查参数有效性.md 50. 必要时进行防御性拷贝.md 51. 仔细设计方法签名.md 52. 明智审慎使用重载.md 53. 明智审慎使用可变参数.md 54. 返回空的数组或集合,不要返回 null.md 55. 明智审慎返回 Optional.md 56. 为所有已公开的 API 元素编写文档注释.md 57. 最小化局部变量的作用域.md 58. for-each 循环优于传统 for 循环.md 59. 了解并使用库.md 60. 若需要精确答案就应避免使用 float 和 double 类型.md 61. 基本数据类型优于包装类.md 62. 当使用其他类型更合适时应避免使用字符串.md 63. 当心字符串连接引起的性能问题.md 64. 通过接口引用对象.md 65. 接口优于反射.md 66. 明智审慎本地方法.md 67. 明智审慎进行优化.md 68. 遵守被广泛认可的命名约定.md 69. 只针对异常的情况下才使用异常.md 70. 对可恢复的情况使用受检异常,对编程错误使用运行时异常.md 71. 避免不必要的使用受检异常.md 72. 优先使用标准的异常.md 73. 抛出与抽象对应的异常.md 74. 每个方法抛出的异常都需要创建文档.md 75. 在细节消息中包含失败一捕获信息.md 76. 保持失败原子性.md 77. 不要忽略异常.md 78. 同步访问共享的可变数据.md 79. 避免过度同步.md 80. executor 、task 和 stream 优先于线程.md 81. 相比 wait 和 notify 优先使用并发工具.md 82. 文档应包含线程安全属性.md 83. 明智审慎的使用延迟初始化.md 84. 不要依赖线程调度器.md 85. 优先选择 Java 序列化的替代方案.md 86. 非常谨慎实现 Serializable.md 87. 考虑使用自定义的序列化形式.md 88. 保护性的编写 readObject 方法.md 89. 对于实例控制,枚举类型优于 readResolve.md 90. 考虑用序列化代理代替序列化实例.md
©️2020 CSDN 皮肤主题: 黑客帝国 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值