吐槽一下JAVA:有人注意到这个问题了吗?
最近从C++转到JAVA,当然学JAVA只是业余爱好,主业仍是C/C++。
[color=#FF0000]一[/color]
我个人觉得JAVA的String类设计得不是很合理。
除了字符串常量在编译时能够确定这种情况下,可以将其放入常量池共享,其它情况基本都不太适合使用。
在运行时创建一个String对象时,如果常量池没有该字符串则创建两个,并将String对象与之关联。
我不明白,为什么非要在常量池中建立一个副本。
有人说,是为了字符串比较速度更快。
我却不以为然,如果你仔细分析就会发现不建立常量池与建立常量池来比较字符串的时间复杂度是一样的。
众所周知,String对象是不可变的,这就意味着如果要改变字符串就会产生新的字符串对象。
我看到书上充斥着大量的例子,它们都在使用String来处理可变的字符串,效率低到令人发指,就好像让你求一个catalan数,你不去总结公式,反而在那里一一穷举一样。
我觉得常量池能提高效率的唯一优势就是在于共享,如果不能共享,其反而弄巧成拙。事实上,有多少人在重复共享呢?
好吧,我找到了可变的字符串类StringBuilder(Buffer),我决定以后主要就使用它了。
它与String在处理字符串应用上一样十分强大,很棒,的确。
可当我从文件中读取字符串来处理时,我傻眼了,好像没有以StringBuilder作为参数的读取方法。你要么使用char[],要么使用String吧。String就算了吧,当我读个几M的文件,这货恐怕要新建一坨一坨的对象吧。
char[]也不错嘛,可是读完后,当我想处理时,我就崩溃了,我恐怕得自己实现所有的方法吧,要是这样,C++就要抽我的脸了!
好吧,我恐怕还得转到String或StringBuilder来,因为它们提供了大量现成的实用方法。这样,又从char[]复制一坨一坨的字符到String(Builder)对象。
大哥,效率啊,我在C/C++中读一遍文件,在JAVA中恐怕无形中要读2到3遍吧,更何况你还是解释型的。
设计者难道觉得设计成直接读到StringBuilder中会很显得极不优雅吗??
[b]二、[/b]
仁者见仁,智者见智的checked exception问题,虽然,这个争论很难达成一致结果,但我还是觉得C#和Python取消checked exception是好的做法。当我看到我的代码中处处充斥着try-catch这种效率极低的语句时或throws声明时,我觉得JAVA还真不优雅!!
[b]三、[/b]
for-each循环,我没有用过,好像只有在看书的时候,把书上的例子敲了一遍。但本能地想到,这货肯定又将对象复制了一遍,因为for-each是只读的,你不可能改变其元素。当对象很大很多时,创建对象的副本绝对是白痴做法。
[b]四、[/b]
泛型!
JAVA的泛型真是鸡肋,我真是佩服设计者能想出“擦除”这种投机取巧的方法。
可能是C++ Template给我的感觉是太优秀了,所以有点不适应JAVA这种绕着弯变戏法似的伪泛型。
[b]五、[/b]
之前一直用记事本,今天下了个eclipse,试用了下,功能还算强大,只不过默认设置不是很好,需要手动更改。
传说中eclipse比较慢,今日一见果然名不虚传,哥I5双核CPU都要一分钟才能打开,你让秒开的CB情何以堪啊!
好了,吐槽完了,这是我初学JAVA后临时的想法。JAVA虽然有瑕疵,但不掩瑜。总体来说,还算不错!
其实,只要是想听听大神们对String类的见解,其它的几条可以忽视了。
PS:本人小菜鸟一只,大神还请嘴下留情,谢谢!!
[解决办法]
虽然现在的大多数JVM实现都采用的JIT形式
但是可以实现这样一种虚拟机:
读取class文件,直接将其编译成native代码,以后一直运行native代码,只是将编译期的动作推迟到了运行期的前期
jvm规范只是规定了它一定要能读懂和执行.class文件,换句话说,jvm的实现很自由,可以实现一个jvm和java编译器,将java代码编译成本地代码,jvm可以选择性的实现识别和执行这种本地代码,但必须要识别和执行class文件,当然,正如楼主所言,不能跨平台了。
GCJ这个编译器可以将java代码直接编译成本地代码,可以研究研究
最后,其实,我想表达的是,jvm的实现自由很大,哦了