重温“ Java Sucks”

总览

关于Java的不足之处(从C开发人员的角度来看)的一个有趣的文档是在一段时间(大约2000年前)写的,但是今天许多论点都像十年前一样真实(或不真实)。
原始的Java Sucks发布。

短消息回顾

Java没有free()。
作者将其列为受益,并且有99%的时间是胜利。 有时候,当您希望进行逃避分析时,没有不利之处 会立即消除,回收或释放您不再需要的对象(恕我直言,JIT / javac应该能够在理论上解决该问题)

词法范围的局部函数
最接近的Java是匿名方法。 对于Closures(Java 8中引入)来说,这是一个差的表亲,但是可以使它做同样的事情。

没有宏系统
您可以使用宏执行许多有用的技巧,Java可以动态地为您执行。 不需要宏系统是一种资产,因为您不需要知道Java何时会为您提供相同的优化。 宏没有应用程序启动成本,并且您无法做真正混淆的事情,但这可能是一件好事。

显式内联函数
JIT可以为您内联方法。 Java可以从共享库内联方法,即使它们是动态更新的。 这确实需要花费运行时间,但是更好的是不必担心此恕我直言。

我发现缺少函数指针是一个巨大的痛苦
函数指针使衬里方法对于编译器更加困难。 如果您使用的是面向对象的编程,那么我认为您不需要这些。 对于其他情况,我相信Java 8中的Closure可能会更好。

静态方法不是真正的类方法的事实是相当愚蠢的
我想大多数Java开发人员都会在某个阶段遇到此问题。 恕我直言:最好的解决方案是将“静态”功能移至其自己的类,并且如果需要多态性则不使用静态方法。

人们如何暗示应该内联一个方法,否则很快就会真正实现,这远非显而易见。
缩小并多次调用。 ;)

两个相同的byte []数组不相等且不散列相同
我同意它的丑陋设计选择不使数组成为合适的对象。 它们继承自Object,但没有toString,equals,hashCode,compareTo的有用实现。 clone()和getClass()是最有用的方法。 您可以改用辅助方法,但是在不同的程序包中有许多不同的辅助类,分别称为Array,Arrays,ArrayUtil,ArrayUtils,这对于新开发人员来说是一团糟。

Hashtable / HashMap确实允许您提供哈希函数
如果您想更改行为,这也是一种痛苦。 恕我直言,最好的解决方案是编写一个实现equals / hashCode的包装器类,但这会增加开销。

迭代字符串中的字符,而不隐式涉及每个字符的六个方法调用
现在有String.toCharArray(),但这会创建您不需要的副本,并且不会被转义分析消除。 如果是这样,这是显而易见的解决方案。 同样的道理也适用于“另一种选择是先将String转换为byte [],然后迭代字节,以创建大量随机垃圾为代价”

在我确定没有非ASCII字符的情况下,Unicode支持会增加开销
Java 6为此提供了-XX:+ UseCompressedStrings解决方案。 不幸的是,Java 7放弃了对该功能的支持。 我不知道为什么要在我做的测试中使用此选项来提高性能(以及减少内存使用)。

接口似乎是一个庞大而俗气的铜版画,可避免多重继承。 他们似乎真的是事后被嫁接了。
我更喜欢只列出所提供功能而不添加实现的合同。 Java 8中更新的虚拟扩展方法将提供无状态的默认实现。 在某些情况下,这将非常有用。

类型提升有些麻烦
Java 5.0+现在支持的协变量返回类型解决了这里的问题。

您不能编写一个期望和对象的函数并给它一个简短的描述
今天,您可以进行自动装箱。 作者抱怨说Short和short不是一回事。 出于效率目的,在某些情况下,使用自动装箱可能几乎没有什么区别。 在某些情况下,它确实有很大的不同,而且我不认为Java在不久的将来会对此进行透明地优化。 :|

如果不知道数组内容的详细信息,就无法遍历数组的内容,这是一种总的痛苦。
很少有您真正需要执行此恕我直言。 您可以使用Array.getLength(array)Array.get(array,n)处理通用数组。 它很丑,但是你可以做到。 它是辅助类之一,它实际上应该是数组本身的方法恕我直言。

处理溢出的唯一方法是使用BigInteger(并重写代码)
诸如Scala之类的语言支持BigInteger的运算符,并且有人建议Java也应如此。 我相信Java 8/9也将考虑溢出检测。

我想念typedef
这使您可以使用基元并仍然获得类型安全性。 恕我直言,真正的问题是JIT无法检测到类型仅仅是原语(或两个)的包装,并且不需要包装的类。 这将提供typedef的优点,而无需更改语法,并使代码更面向对象。

我认为用于模拟枚举和:keywords的可用习语相当la脚
Java 5.0+具有枚举 ,它们是一流的对象,并且功能强大。

没有有效的方法来实现“断言”
assert现在已内置。JIT可以自己实现它。 (大概不是十年前)

通过使“新”成为分配的唯一可能接口,……就有了一整类古老的,众所周知的优化,人们根本无法执行。
这应该由JIT IMHO执行。 不幸的是,它很少这样做,但是这种情况正在改善。

敲定系统很la脚。
大多数人都认为最好避免。 也许它可能更强大,更可靠。 答案可能是ARM(自动资源管理)。

相关地,没有“弱指针”。
Java一直都有弱,软和幻像引用,但是我怀疑这不是这里的意思。 ??

除了内部变量中的最终变量,您什么都不能关闭!
匿名内部类是正确的,但引用字段的嵌套内部类则没有。 封闭可能没有此限制,但可能同样令人困惑。 由于习惯了最终变量的要求,我尤其没有发现这个问题。 因为我的IDE会根据我的要求更正代码。

关于对象的可变性(或只读性)的访问模型受到打击
主要的抱怨似乎是有一些方法可以将最终字段视为可变的。 这是反序列化和依赖注入程序所必需的。 只要您意识到自己有两个可能的行为,一个级别比另一个级别低,它就会比问题更有用。

该语言还应规定字面常量是不变的。
文字常量是不可变的。 看来作者想扩展什么是文字常量。 恕我直言,以C ++的方式支持const很有用。 const是Java中的关键字,而无需创建多个实现或只读包装器来定义类的不可变版本的功能将更有效率。

锁定模型已损坏。
锁定问题的内存开销实际上是一个实现细节。 由JVM决定标头的大小以及是否可以锁定标头。 另一个问题是无法控制谁可以获取锁。 解决此问题的常用方法是封装您的锁,这是您在任何情况下都必须要做的。 从理论上讲,锁可以被优化掉。 当前,只有在优化整个对象时才会发生这种情况。

没有抛出就没有信号
为此,我将侦听器模式与onError方法一起使用。 语言对此没有支持,但我认为没有必要。

应该将foo.x定义为等同于foo.x(),
也许foo.x => foo.getX()会是更好的选择,就像C#一样。

编译器应该能够轻松地内联零参数访问器方法,以内联对象+偏移量加载。

JIT这样做,而不是编译器。 这样就可以在编译被调用方之后更改调用代码。

方法“属于”类的概念是la脚的。
这是某些语言支持的“酷”功能。 在更动态的环境中,这看起来更好。 不利的一面是,您可以在整个地方为某个类编写一段代码,并且您将不得不采用某种方式来管理不同库中的重复项。 例如,库A定义了一个新的printString()方法,库B也为同一类定义了一个printString方法。 您将需要使每个库看到其自己的副本,并具有某种方法来确定C调用此方法时需要哪个版本的库。

图书馆

它带有哈希表,但没有qsort
它带有一个“优化的合并排序”,旨在加快速度。

字符串的长度为+ byte []的开销+24个字节
也就是说,无需考虑两个对象中的每个对象都与8字节边界对齐(使其更高)。 如果听起来很糟糕,请考虑将malloc对齐16字节,最小大小为32字节。 如果将shared_ptr用作byte [](以提供类似的资源管理),则在C ++中,它可能比Java大得多。

造成这种开销的唯一原因是String.substring()可以返回共享相同值数组的字符串。

这是不正确的。 问题是Java不支持可变大小的对象(数组除外)。 这意味着String对象是固定大小的,要拥有可变大小的字段,您必须拥有另一个对象。 无论哪种方式都不是很好。 ;)

String.substring可能是“内存泄漏”的来源
您必须知道要对您进行显式复制,才能保留较大字符串的子字符串。 这很丑陋,但是好处通常超过了缺点。 更好的解决方案是能够优化代码,以便默认情况下采用防御性副本,除非不需要防御性副本(已将其优化掉)

文件操作原语不足
Java 7中改进了文件系统信息。我认为这些选项不可用,但是如果您需要知道这些选项,则可以很容易地推断出它们。

这不是问“我在Windows上运行”还是“我在Unix上运行”的可靠方法。
系统属性os.name,os.arch,os.version一直存在。

在Unix上无法访问link(),这是实现文件锁定的唯一可靠方法。
这是在Java 7 创建硬链接中添加的

除了复制并重命名整个文件外,没有其他方法可以执行ftruncate()。
您可以使用RandomAccessFile.truncate()。 在Java 1.4中添加。

“%10s%03d”真的有太多要求吗?
它是在Java 5.0中添加的

RandomAccessFile不能用作FileInputStream或FileOutputStreamRandomAccessFile

支持DataInput和DataOutput,FileInputStream和FileOutputStream可以包装在DataInputStream和DataOutputStream中。 可以使它们支持相同的接口。 我从未遇到过要在单个方法中同时使用两个类的情况。

markSupported是愚蠢的
真正。 有许多愚蠢的方法只是出于历史目的。 另一个是在每个对象(甚至数组)上的Object.wait(millis,nanos ),但是nanos从未真正使用过。

世界和系统运行时之间有什么区别?
我同意这似乎是任意的,在某些情况下会增加一倍。 System.gc()实际上调用Runtime.getRuntime()。gc(),但即使在内部代码中也被称为System GC。 在后站点中,它们实际上应该是一类,并将监视功能移至JMX。

世界上是在基础语言类库中进行的像checkPrintJobAccess()这样的应用程序级废话
因此,您的SecurityManager可以控制是否可以执行打印。 (也不必具有应用程序级安全性管理器)不确定是否确实阻止了对应用程序级安全性的需求。 ;)

参考:在Java Java博客上,我们的JCG合作伙伴 Peter Lawrey 重新审视了“ Java Sucks” 。


翻译自: https://www.javacodegeeks.com/2012/01/java-sucks-revisited.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373806.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio IDE Out of Memory

场景: 尝试过各种方式,IDE重装,重新启动,设置IDE MEMORY大小JDK MEMORY大小都无效 终于在FILE->INVALIDATE CACHES/RESTART 中点击重新启动之后问题攻克了。转载于:https://www.cnblogs.com/yxwkf/p/5128094.html

git 忽略 部分文件夹_git设置忽略文件和目录

1.登录gitbash命令端进入本地git库目录AdministratorPC201601200946 MINGW32 /d/gitrespository/crmweb (master)2.创建.gitignore3.修改文件,添加忽略正则.idea //忽略.idea文件夹及文件夹下文件*.iml //忽略以.iml结尾的文件【例子】# 忽略*.o和*.a文件*.[oa]# 忽…

在Spring MVC REST应用程序中自动生成WADL

上一次我们学习了WADL的基础知识 。 语言本身并没有那么有趣,只写了一篇有关它的文章,但是本文的标题揭示了为什么我们需要这些知识。 JSR 311的许多实现:JAX-RS:RESTful Web服务的Java API提供了开箱即用的运行时WADL生成&#x…

JSP静态导入与动态导入

JSP静态导入(JSP指令标记include) JSP页面第一次被请求时,会被JSP引擎转译成Servlet的Java文件,然后再被编译成字节码文件执行。JSP指令标记为JSP页面转译提供整个页面的相关信息。 include指令用于在JSP页面静态插入一个文件&…

关于DJANGO和JAVASCRIPT的时间

最近,实际一些简单统计时,要到库里去检索数据出来用HIGHCHARTS画图, 作一个简单的回照。。 DJANGO用TEMPLATEVIEW来作。专业,正规:) class SAView(TemplateView):template_name version/sa_site.htmlpagin…

git里面的文件怎么删不掉_.git目录删不掉

这样的情况并非是第一次遇到了,以前总是会觉得这样的问题只是电脑的错乱,重启一下电脑就好了,但是并非每次都需要重启电脑的,其实简单的设置一下,这个问题就可以解决了。对了,咱们还是说说这到底是个什么问…

集成框架比较– Spring集成,Mule ESB或Apache Camel

公司之间的数据交换增加了很多。 必须集成的应用程序数量也增加了。 这些接口使用不同的技术,协议和数据格式。 但是,这些应用程序的集成应以标准化的方式建模,有效实现并由自动测试支持 。 JVM环境中提供了三个可满足这些要求的集成框架&…

Vue.js组件学习

组件可以扩展HTML元素&#xff0c;封装可重用的HTML代码&#xff0c;我们可以将组件看作自定义的HTML元素。组件系统提供了一种抽象&#xff0c;让我们可以使用独立可复用的小组件来构建大型应用。 一个简单组件例子(全局注册&#xff09; <!DOCTYPE html> <html>&…

Winform MD5

1&#xff1a;MD5 http://www.cmd5.com/ 字节数组----字符串 //将字节数组中每个元素按照指定的编码格式解析成字符串//直接将数组ToString()//将字节数组中的每个元素ToString() //ToString("Params") ToString("x") //可以将十进制字符串转换为16进制字符…

HTML元素显示与隐藏

在WEB开发中&#xff0c;前台HTML中经常需要控制元素的隐藏与显示&#xff0c;我们最为最常见是二级导航栏&#xff08;通过鼠标的移动来触发onmouseover&#xff0c;onmouseout事件来实现二级菜单的显示与隐藏&#xff09;二级菜单的显示与隐藏。 然而控制元素的影响与显示有…

书评:JavaFX 2.0:示例介绍

尽管Oracle在JavaOne 2010和JavaOne 2011上对JavaFX的更改使我从怀疑论者转变为对JavaFX的信奉者 &#xff0c;但是JavaFX愿景的转变并非没有缺点 。 特别是&#xff0c;JavaFX图书市场一直很棘手&#xff0c;因为几乎所有可用的JavaFX图书都与1.x版本有关。 在这篇文章中&…

脑子越来越不好使,文字越来越像驮shi

没办法&#xff0c;还是记下来。。。转载于:https://www.cnblogs.com/thorlet/p/5926595.html

python机制_python异常机制个人理解(参考网上资料)

当你的程序中出现异常情况时就需要异常处理。比如当你打开一个不存在的文件时。当你的程序中有一些无效的语句时&#xff0c;Python会提示你有错误存在。下面是一个拼写错误的例子&#xff0c;print写成了Print。Python是大小写敏感的&#xff0c;因此Python将引发一个错误&…

NYOJ 24 素数距离问题

素数距离问题 时间限制&#xff1a;3000 ms | 内存限制&#xff1a;65535 KB难度&#xff1a;2描述 现在给出你一些数&#xff0c;要求你写出一个程序&#xff0c;输出这些整数相邻最近的素数&#xff0c;并输出其相距长度。如果左右有等距离长度素数&#xff0c;则输出左侧的…

C#控件大小随窗体大小等比例变化

相信很多博友在开发初次接触学习C# winForm时&#xff0c;当窗体大小变化时&#xff0c;窗体内的控件并没有随着窗体的变化而变化&#xff0c;最近因为一个项目工程的原因&#xff0c;也需要解决这个问题。通过查阅和学习&#xff0c;这个问题得到了解决&#xff0c;或许不是很…

Google Appengine登台服务器操作方法

Google的App Engine开箱即用&#xff0c;支持版本化部署。 您可以非常轻松地在各修订版之间来回切换&#xff0c;这是在上线之前正确测试应用程序的一项很棒的功能。 有一个主要问题&#xff1a;应用程序的所有版本共享同一数据存储。 因此&#xff0c;如果要迁移数据&#xff…

下 面 这 条 语 句 一 共 创 建 了 多 少 个 对 象 : String s=a+b+c+d;

javac 编译可以对字符串常量直接相加的表达式进行优化&#xff0c; 不必要等到运行期去进行加法运算处理&#xff0c; 而是在编译时去掉其中的加号&#xff0c; 直接将其编译成一个这些常量相连的结果。题目中的第一行代码被编译器在编译时优化后&#xff0c; 相当于直接定义了…

公共样式_设计干货 | 园路铺装的100种样式,保存收好

Part 1园路的形式主干道&#xff1a;联系全园&#xff0c;必须考虑通行、生产、救护、消防、游览的需要。次干道&#xff1a;沟通各景点、建筑&#xff0c;通轻型车辆。休闲小径、健康步道&#xff1a;健康步道是近年来最为流行的足底按摩健身方式。通过行走卵石路上按摩足底穴…

22个所见即所得在线 Web 编辑器

新闻来源:sixrevisions.com我们曾介绍过 10 个基于 JavaScript 的 WYSIWYG&#xff08;所见即所得&#xff09; 编辑器&#xff0c;这些 Web 编辑器可以在线编辑和处理富 Web 内容&#xff0c;包括格式文本&#xff0c;表格&#xff0c;图片&#xff0c;媒体&#xff0c;链接等…

配置阿里云作为yum 源

第一步&#xff1a;下载aliyum 的yum源配置文件。 http://mirrors.aliyun.com/repo/ 第二步&#xff1a;把下载到的repo文件复制到/etc/yum.repo.d/目录下。 ----------------------------------------------------下面是本地yum源的一个例子 [base_extra]namebase & extra…