如果是new String,形如new String("avc");是有两个,因为new本身就是去要求一个新对象,没办法,另外一个就是缓存起来的另外就是String#intern方法,两个具有相同码点序列的的String对象调用intern后得到的应该是同一个对象。那么对于这种呢: String a = new String(args[0]); boolean b = a == a.intern();不同的jvm实现还真的不一样,hotspot跟jrocket就不一样,hotspot1.6与hotspot1.7之前的版本也不一样,究其原因是规范中并没有规定其行为。这两个链接不得不看: http://www.iteye.com/topic/774673http://www.iteye.com/topic/1112592
这个你只能去吐糟微软了,看样子你是在用Windows吧,我5年前的MacBook Pro,CPU只是双核2.4G,打开Eclipse 4.2只需要10秒左右,刚刚才打开数了一下,正好10秒。
虽然,我JAVA没你好,但我相信编译原理我比你懂得多不要说JIT,任何狭义的编译型语言都不能跨平台
读取class文件,直接将其编译成native代码,以后一直运行native代码,只是将编译期的动作推迟到了运行期的前期jvm规范只是规定了它一定要能读懂和执行.class文件,换句话说,jvm的实现很自由,可以实现一个jvm和java编译器,将java代码编译成本地代码,jvm可以选择性的实现识别和执行这种本地代码,但必须要识别和执行class文件,当然,正如楼主所言,不能跨平台了。GCJ这个编译器可以将java代码直接编译成本地代码,可以研究研究
最后,其实,我想表达的是,jvm的实现自由很大,哦了
只不过我不像某些狂热的JAVA沙文主义者一味吹捧JAVA....
char [5],你想加一位就要做个char[6]然后copy再加一位,string适合reference运算。StringBuilder又不是每次加一个字符串就copy一次,他是申请一段内存,当发现不够了,再扩大一次。
基本上是int newCapacity = value.length * 2 + 2;而且复制数组是调用c或者操作系统的copy方式,所以效率不是他负责的。文件读取最基本的是字节流,就是char,你所说的什么string估计就是加了个修饰,自己做了个buffer拼接,而且读文件又不是java调用的,底层那块调用是交给操作系统的.
哥读写文件写过无数,从来没听说要读两遍的,不知道你怎么看书的。
foreach只是能让你能拿到对象的reference,谁你和说是复制一遍,你拿到reference了,当然可以改变对象内容,和foreach没半毛钱关系。另外eclipse又不是存java开发的,底层那块都是用c++写的。
最后吐槽一下,楼主的学习能力,简直令人发指。呵呵
String a = new String(args[0]);
boolean b = a == a.intern();不同的jvm实现还真的不一样,hotspot跟jrocket就不一样,hotspot1.6与hotspot1.7之前的版本也不一样,究其原因是规范中并没有规定其行为。这两个链接不得不看:
http://www.iteye.com/topic/774673http://www.iteye.com/topic/1112592
我当然知道,String的char[]不能动态扩展,StringBuilder能动态扩展,这些和C/C++一样的道理。
凡事学过数据结构都知道其如何实现的。特别是C++的STL实现更是如此
我也没说,文件要读两遍。我的意思是我读文件时,我需要额外建立一个char[]数组吧,然后,我想对读取的字符串进行处理,我必须要转到String或StringBuilder吧,从char[]到String或StringBuilder对象难道不需要复制操作???如果直接将StringBuilder作为文件读取参数,就省掉了char[],直接读到StringBuilder的char[]里面,这样既省空间也省时间读文件底层当然是系统调用,但这并不代表所有读文件的效率只跟OS有关,那所有语言本质都是二进制,慢的是不是也跟语言没关系,怪CPU呢???还有我的重点是将String设计成这样,没有很大的必要,因为没有理由表明这样效率更高。像C++这样copy-on-write就够了!最后,重申一下,我不是在攻击JAVA,只是说说我觉得不合理的地方,任何语言都有优劣。对于C/C++,我也吐槽过。我这里只想听听大神们的意见,仅此而已。
至于JVM的底层和class文件结构,我倒是没有研究,毕竟我只是业余鼓捣一下JAVA
FileUtils.readFileToString(new File("F:/new.txt"));往简单的地方想,做C/C++还不是同样得用一些可靠的类库吗。自己去写那些底层的东西基本上是无用功,难道你是计算机科学家?你想了解StringBuilder,看一下它的源代码不就得了。
-----------------------------------------------------------
Java泛型设计时,需要尽量使 byte code 向前兼容。泛型的目的无外乎:
1 - 同一段代码让不同类型复用
2 - 帮助程序员检查类型,即类型安全从这个意义上说,Java泛型达到了其设计目的。有谁规定泛型必须怎么实现才叫“真泛型”,怎么实现就叫“假泛型”么?编译时检查甚至比运行时检查更好,因为节省了运行时类型检查的成本。“这件事在C++里能做,在Java里不能做,所以 C++ > Java”Java认为:这件事 没有必要/可以用别的方式实现/易导致程序员出错
这件事 不能做 > 能做
-----个人觉得checked exception的设计本意是好的,有些地方被滥用了。
在下本人也觉得Java的泛型设计很鸡肋,由于类型擦除造成的多余的装、拆箱操作确实很影响效率。
由于我是C/C++临时转过来的,编程时可能对效率不经意地就比较关注了。解释型语言都逃不过这一命运。我的意思是,JAVA本可以再提高一点执行效率,就是在细节问题上处理地更好一点,虽然性能提升可能微乎其微。
确实,JAVA的优势在于开发效率、跨平台以及其成熟性。
如果你要将文件char[]数组转到string主要不是因为copy ,是因为要将字节重新编码,我觉得你至少要知道,比如UTF-8.gb编码方式都不一样,一个汉字所占的字节都不一样,你直接读,编码格式都没有,必定乱码。如果你是处理二进制数据不需要转成string,直接处理字节就可以了。这点你可以看看c#,几乎一模一样。读文件主要是磁盘的io还有操作系统有关,和你那种语言写关系不大。
一般优化都是考虑怎么优化io。可以说绝大部分新手写java感觉的到的效率问题,是由于设计方案和一些硬件问题造成的,和用那种语言问题不大,只是一些人为了推卸责任,找个东西怪一下。
char [5],你想加一位就要做个char[6]然后copy再加一位,string适合reference运算。StringBuilder又不是每次加一个字符串就copy一次,他是申请一段内存,当发现不够了,再扩大一次。
基本上是int newCapacity = value.length * 2 + 2;而且复制数组是调用c或者操作系统的copy方式,所以效率不是他负责的。文件读取最基本的是字节流,就是char,你所说的什么string估计就是加了个修饰,自己做了个buffer拼接,而且读文件又不是java调用的,底层那块调用是交给操作系统的.如需其他java技术方面的帮助和支持,欢迎加入我们的java开发联盟。
群号:
247286682
群里有来自全国各地的java开发高手与你一起探讨java技术,共同进步。 来者请注明:csdn.
你如果不喜欢直接读string,可以读buffered stream,然后封装到stringbuffer中去,其实并不慢多少
你哪里看出来我带着歧视的情绪在学JAVA?
你哪里看出来别人回复我看不懂?
你又哪里看出来我搞不懂解释与编译的区别?可笑,哥堂堂一个985名校的学生,虽然做的项目没有你们多,但论计算机理论和数字逻辑,我自信甩你一条街还是可以的(你可以认为哥是在炫耀,也可以葡萄酸地自认为名校名实难副)。纵然你学过所有的编程语言又如何??我从不认为任何编程语言是难学的(当然深入到语言本身构造除外)!!最后,给你个忠告: 凡事不要自以为是地强奸他人的意思,这样,你比较少后悔些!!
每个语言都有自己的特点,使用范围,封装程度
C,python,php 我也都用过,而且用得不少
JAVA在乎吗?效率差的不用就是了 难的都再封装 变成最简单的给人用
这些都是语言的哲学不同带来的 和各自应用领域有关 两者无所谓好坏
至于语言有设计不合理的地方也蛮正常 都有 天下有没有BUG的程序吗?
楼主不淡定啊~ 尺有所短,寸有所长,Java在效率方面与原生语言肯定不能比(现在也没有人再去比较这个了,目前的机器配置,效率已经不是什么重要的指标了),常量池设计肯定有它的道理,在很多时候,很多字符串在程序中是多次使用的,特别是相临上下文中,一些字符串会大量重复使用(Python在初始化时候也会cache很多常用的对象),如果编译期间能够确定使用的字符串是同一个,bytecode指令还是使用相同的索引(相同的Reference),至于你说的大量类似+=运算符产生的临时String对象,这种情况在C++也存在,C++的临时对象大量存在(造成很多构造,析构过程),在C++我们可以通过使用引用方式杜绝这些低效率的情况,正如Java中也可以通过其他方法杜绝你说的情况。我读取文件,一般使用流,如果是文本文件然后再一次性转换为String(转换的时候再统一处理编码,当然不是大文件了)。
不同平台Java的实现,根据硬件的不同,估计在这个部分会有不同程度的优化(估计的,没有看过其他平台的VM实现)。
个人感觉,String目前的设计是有必要,如果在意效率,可以选择其他处理方式(比如StringBuilder和流方式处理)。
既然CSDN解决不了你的问题,你可以去sun、oracle论坛嘛。
写源代码的人又不是上帝,难免会有缺失。
而且看你贴子的语气跟内容,你好像不是单纯来询问String类的事吧。也不是单纯讨论java机制的劣势的吧。
还有你说学JAVA的是三流码农,这就不好了。就像我总是说学C的是普通青年,学JAVA的是文艺青年一样。
还有啊,高手都忙着写代码,谁还逛CSDN,高高手都坐在各IT公司的高高层了,没人理你。
我建议你可以给JAVA之父james发邮件讨论这些问题,我想你会收获更多,总比来这跟人吐槽好吧。
还有,除非你能自己编写出克服以上缺失的语言或方法,不然你还得努力寻找合适的API去编写代码。
不要总拿比较的眼光去学各种语言。
弱弱地问一下,你把JAVA当做业余,是不是想从一些方面提高对C++的兴趣啊。
如果你实在受不了了,建议你还是学C++吧~~
我看到书上充斥着大量的例子,它们都在使用String来处理可变的字符串,效率低到令人发指,就好像让你求一个catalan数,你不去总结公式,反而在那里一一穷举一样。
---------------------------------------------------
String 对象不可变,是因为它是基本的数据类型。没想过可变会如何。
想请教一下,在c++怎么一次性将几M的文件读进string ?我一般处理也是这样,循环读取固定字数的字符,然后拼接(见后),有啥更好的方法?while (!文件结束)
{
fgets读取1024字节
拼接到string对象结尾
}
你认为把String设计成StringBuilder一样可变就能带来性能上的提升?
那么,char[]部分冗余的空间怎么把握?
少了浪费(白冗余了,还是要另申请空间),多了也浪费(多的用不上),还要另外字段记录偏移量,又是浪费。
所以,String不可变是完全正确的。
你要是要变,就用StringBuilder去,工具都提供了,用得愚蠢是你自己笨。另外,str1 + str2,编译器会优化成StringBuilder.append(str1).append(str2)。
其他的不说了
读文件倒是有个一次读成BYTE的函数,RandomAccessFile,但是转化成string的时候又需要指定编码类型,可以相像一下,这里编码转换又浪费不少效率,另外,哥的字符串是几种编码混编的,蛋疼了。最后还是有办法解决,反正JAVA“不用”考虑效率嘛。这些问题我也咨询过我做JAVA的同学,7年经验,绝对算是高手了。他说没办法解决,他们压根就用不到这么复杂的字符串处理的。
哥也吐槽一个问题:为毛JAVA中基本类型无法传”引用“,需要在函数中改变一个基本类型的时候很蛋疼,当然你可以说用return,但是要多个基本类型值呢?难道让我把这个组装成一个类再返回(我还真就这么做的^-^).
PS:我也是主要做C/C++的,涉及少量C#或者JAVA,个人感觉就基本语法方面而言,C#貌视改进了某些JAVA在语法上的不足方面,略微好些。
上面很多同学都说语言侧重点不同,你们说的很对,但是我想说一句,JAVA把string改进一下完全可以做得很好,为什么却不做?或许是有我还没弄懂的深层原因吧?