轉(zhuǎn)帖:JAVA無用論
發(fā)表時間:2023-07-29 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]JAVA無用論 2000-10-24 1. 寫這篇文章的目的 學(xué)了一些關(guān)于Java的東西,個人認為它很不好用。為了減少上當人數(shù) 特寫此文。 盡管 java 宣稱它是100%面向?qū)ο螅鳦++不是。但...
JAVA無用論
2000-10-24
1. 寫這篇文章的目的
學(xué)了一些關(guān)于Java的東西,個人認為它很不好用。為了減少上當人數(shù)
特寫此文。
盡管 java 宣稱它是100%面向?qū)ο,而C++不是。但是宣稱100%面向
對象本身就不是什么面向?qū)ο蟮乃枷。面向(qū)ο蟮谋举|(zhì)目的是提高生
產(chǎn)率。討論一種語言是否100%面向?qū)ο缶秃孟裼懻撐覀兊纳鐣再Y性
社一樣滑稽。其實學(xué)習(xí)面向?qū)ο蟛灰欢ǚ且褂胘ava不可。我反而認
為120%面向?qū)ο蟮腃++是不錯的選擇。
Java號稱跨平臺,其實這是只一個夢想,也不妨用騙局這個詞來形容
。軟件的移植性僅僅和虛機相關(guān)嗎?照此理論是不是可以說符合IA32
體系的軟件在任何IA32體系上都能正常運行。那我怎么沒看見SCO:
:lf 在 NT上運行?顯然,除了虛機,軟件二進制規(guī)范(執(zhí)行文件格
式、連接方法)、運行時間庫和系統(tǒng)調(diào)用也是軟件移植問題因素。而
java規(guī)范中顯然不包括完整的運行時間庫和系統(tǒng)調(diào)用,甚至二進制規(guī)
范也有不兼容的地方(比如本原接口和固有接口)。軟件總不能脫離
它的運行環(huán)境,不兼容就從這里開始。
要提高軟件生產(chǎn)效率。應(yīng)當認認真真的研究系統(tǒng)結(jié)構(gòu)、二進制規(guī)范、
系統(tǒng)調(diào)用結(jié)構(gòu)才是解決問題的方法。靠概念游戲這種投機取巧的方法
是行不通的。
我說java不好,甚至不必對其側(cè)目,你信嗎?我估計信的人不多。我
只是想說“上當之后別怪我沒說”。
另外如果您在Java中發(fā)現(xiàn)了甜頭也不妨告訴我;ハ鄬W(xué)習(xí)嗎:)。
2. Java究竟是什么?
Java是一種虛擬硬件系統(tǒng)結(jié)構(gòu),是一種軟件二進制規(guī)范,是一種編程
語言。當我們看到Java一詞時,它可能表達上述三個含義鐘的任何一
個。盡管這三個東西可以獨立存在,不過實際上他們總是在一起出現(xiàn)
。所以也很少有人分的那么明確。使用Fortran語言編寫Java虛機上
的代碼理論上是可行的。但是有誰樂意做這件事呢?
作為虛擬硬件體系結(jié)構(gòu),
Java虛機和ALPHA、PowerPC、SPARC、IA32、51、960是同一概念上的
東西。也許您會奇怪?他們怎是同樣的東西呢?IA32不就是PIII、PI
V那一大塊嗎?其實不然、我們知道386、P5、P6、P7的內(nèi)部結(jié)構(gòu)非常
不同。屬不同的微體系。但是他們實現(xiàn)了相同的IA32指令集合。IA32
也不一定非要通過硬件實現(xiàn),通過軟件也可以。這種軟件CPU產(chǎn)品廣
泛出現(xiàn)在操作系統(tǒng)和CPU密集軟件的開發(fā)、調(diào)試工具上。主要用于在C
PU出現(xiàn)之前調(diào)試軟件。Java指令集同樣也可以通過硬件實現(xiàn)。只是在
半導(dǎo)體工業(yè)激烈競爭的時代,沒有大公司(含SUN)愿意把這么做。
SUN常常說M$很害怕java。他們之間的確存在很強的競爭關(guān)系。倒不
是Java高級語言的問題,我認為是Java二進制規(guī)范和 Windows操作系
統(tǒng)存在競爭。不妨考察Java中的(.class文件格式、裝入方法、執(zhí)行
過程、JDBC接口、J3D接口)和Windows中的(PE文件格式、DLL文件格
式、裝入、連接方法、ODBC、Direct3D)。就知道競爭多么強烈。和N
T/IA不同。Java.exe執(zhí)行程序包含虛機規(guī)范和二進制規(guī)范。在NT/IA
中是分離的產(chǎn)品。
人們總喜歡把Java高級語言和C++類比,他們之間的確存在很過相似
的地方。不過我認為C++和Java不存在什么競爭。它們使用在不同的
場合。他們的區(qū)別(內(nèi)存管理、對象類型、線程規(guī)范)決定他們的用
途。用形似而神不似來形容C++和Java吧。僅從高級語言方面來看。J
ava真正競爭來自ECMAScript 。也就是JScript和VBScript。
3. Java虛機和IA32比較
Java VM和IA32最大的區(qū)別是Java VM的主要實現(xiàn)不考慮效率問題。由
此派生出寄存器少,指令結(jié)構(gòu)簡單(同樣功能生成的程序代碼長),
尋址空間小,尋址方法少、數(shù)據(jù)類型少等。除了上述問題,Java VM
沒有涉及指令(顯式或隱式)并行問題。
3.1. 基本特性差別
3.1.1. 數(shù)據(jù)類型比較
Java VM
IA32
整數(shù)類型
byte
short(16bit) char(UnionCode)
int
long (64bit)
{不存在無符號算術(shù)運算指令,另外注意這里沒有boolean類型}
byte
Word(16bit)
DoubleWord(32bit)
QuotaWord(64bit)
DoubleQuotaWord(2*64bit)
BCD/PackedBCD
BitField
{存在有符號和無符號兩種運算指令}
浮點類型
float(32bit)
double(64bit)
float(32bit)
double(64bit)
long double(80bit)
Packed double(2*64bit)
地址
returnAddress*
8bit , 16bit , 32bit , 48bit都有
沒有顯示的看到returnAddress
類型的寬度,不過。通過指令goto(0xa7)和goto_w(0xc8)來看。retu
rnAddress是可以是16位或32位的。
關(guān)于double和Long的原子問題:在目前的java規(guī)范中,double和long
作為兩個獨立的32 位數(shù)據(jù)獨立存取。這樣可能產(chǎn)生同步問題。歷史
上Intel的CMPXCHG8B(Pentum pro以上CPU提供)指令就存在過類似
問題,一度被指責(zé)是CPU設(shè)計問題。好在CMPXCHG8B很少使用,沒有造
成什么事故。
3.1.2. 指令集
指令類型
JavaVM
IA32
Load/Store
1) 數(shù)據(jù)和運算棧之間單個移動
2) 常數(shù)移入運算棧
1) MOVE
2) CMOVEXX
3) 交換,瑣操作
4) PUSH/POP
5) PUSHA/POPA
6) IN/OUT
元算指令
add , sub , mul , div , neg , rem , shl , or , and , xor
比Java多多了,主要多在顯式并行上
類型轉(zhuǎn)換
基本類型之間可以互相轉(zhuǎn)換
有(由于類型很多,轉(zhuǎn)換指令也有很多)
方法調(diào)用
4條指令
一大堆,主要多在權(quán)限切換(調(diào)用門)、長短跳傳不同上。
3.1.3. 異常
雖然JavaVM有異常的支持,不過很簡單。它不區(qū)分中斷、陷阱和故障
。也不能明確指出出錯代碼的PC,并返回那里重新執(zhí)行。
3.1.4. 執(zhí)行態(tài)
Java VM沒有用戶態(tài)和系統(tǒng)態(tài)執(zhí)行區(qū)分。當然也沒有MMU(管理內(nèi)存分
頁、分段的內(nèi)存管理單元).除非被Java高級語言限制,java VM匯編
代碼也能完成一些惡意操作。
3.1.5. 小結(jié)
總而言之,Java VM很簡單。SUN總是認為通過編譯優(yōu)化Java可以達到
C++速度。顯然是謊言。如果要編譯成本地代碼,顯然要丟失移植性
。如果不編譯成本地代碼,效率問題如何解決?有一種及時編譯的設(shè)
計。對于很小的應(yīng)用也許可行。對于規(guī)模的應(yīng)用呢?要知道優(yōu)化編譯
很費CPU和內(nèi)存。像IA64體系的優(yōu)化方案,要編譯很多遍才能優(yōu)化完
成。要運行時刻編譯是不是天方夜譚。
4. Java高級語言和C++、JScript比較
4.1. 效率,謊言
很多書上寫Java是很快的語言。這時一定要看清楚是比誰快。語句傳
了幾本書難免有些誤差,比較對象經(jīng)常有意無意丟失。一般認為Java
比JScript快。的確快很多,不只十倍。我也承認Java比JScript快。
但有人說Java和C++效率接近。這就是騙人了。他們也能做出試驗證
明,試驗結(jié)果好像也能證明結(jié)論。他們的實驗大概都是形如這樣。
Java, C++測試代碼:
for ( I = 0 ; I<100 ; I++ )
{
RemoteCall( I ); //外部調(diào)用,調(diào)用一次用1s。
}
結(jié)果:
Java 102s , C++ 100s。
結(jié)論:
Java達到了C++ 98.0%的效率。
這種測試違背了測量學(xué)中要把測試對象放到主要矛盾上這一基本原
理。方法的不正確當然帶來了測試結(jié)果的不正確。有本事比比
for ( I = 0 ; I<10000; I++)
{
y = x * z; //由Java語言或C++語言實現(xiàn)執(zhí)行體
}
我的結(jié)果是170倍。也就是PIII變成了286。如果使用指令并行優(yōu)化
,C++和Java的速度差異可以達到千倍以上。想用一下8088嗎?
4.2. 功能缺失導(dǎo)致代碼膨脹
簡單的說,Java比C++缺少編譯預(yù)處理、缺少運算符重載、多繼承和
類模板。我認為取消這些概念很粗暴。和C++不同。對于大規(guī)模編程
來說,Java的代碼量不會比C少多少。甚至由于類型約束太強。有可
能比C的代碼量還大。
Java常稱多繼承比較困難,所以要取消。而且使用實現(xiàn)接口的方法可
以代替C++的多繼承。但是,實現(xiàn)接口要自己寫所有的接口實現(xiàn)代碼
。不嫌煩就慢慢寫吧。
為什么要取消運算符重載?真是不可理解,既簡單又好用。它居然說
難,且容易造成混亂。
總之,處理這幾個大方向的問題,還有很多小問題。據(jù)說AWT不好用,
感覺他們?yōu)榱送瓿扇蝿?wù)寫程序。
4.3. 簡單的騙局
自古便宜沒好貨。Java總是宣揚Java如何簡單,主要宣揚的好處是垃
圾自動收集和線程同步。其實不然,由于Java沒有釋放關(guān)鍵字。使得
不能及時釋放或定時釋放不必的數(shù)據(jù)。要知道能夠分配的不只是內(nèi)存
,還有數(shù)據(jù)庫句柄、文件句柄、結(jié)果集等。這樣不得不繞來繞去的完
成這些任務(wù)。其實C++的析構(gòu)函數(shù)是自動調(diào)用的,也不用自己手動掉
用。遇到一些特殊情況,C++也能很好的解決。
也許java的線程比較簡單吧,不過C++中也可以繼承線程類。由于本
人沒有涉及線程編程。這里不好亂說。
5. Java的兼容性
相對本地代碼來說,Java程序的確移植性比較好。歸其原因不外有二
。一來Java虛機只一種(不像天下有很多種CPU),二來Java二進制
規(guī)范只有一種(不像這么多種操作系統(tǒng))。但是,Java代碼真的可以隨
心所欲的移植嗎?其實不然,上述兩條中的任何一種不再滿足,都會
影響B(tài)yteCode的移植性。
現(xiàn)在,Java的主要版本已經(jīng)有1.0 , 1.1.7 , 1.2(2.0)三個。更殘酷
的是1.1.7和1.2不兼容。一個很著名的例子。Websphere不能在Java1
.2上運行。另外WebLogic不能在1.0上運行。
java的二進制規(guī)范呢?jview( MS java)就自立門戶。他的.class裝
入方法就和java for win32不同。另外它提出了其他的本地代碼連接
方法。顯然這里也會造成不兼容。
除了上述兩條重要的原因,還有就是程序的運行環(huán)境。比如操作系統(tǒng)
是否區(qū)分文件名的大小寫。數(shù)據(jù)庫是否中調(diào)用都能返回執(zhí)行成功。EJ
B的代碼是否有EJB 的運行服務(wù)器。等等。
6. 在精通Java之前否定Java
本人只是對Java略知一二。為什么就非要否定java呢。其實,從一般
科學(xué)觀點審視java。就會發(fā)現(xiàn)其中的問題。
6.1. Java代碼不符合從簡單到復(fù)雜的認識規(guī)律
代碼比較:
Java Code Example:
import java.applet.*;
import java.awt.Gaphics;
public class HelloWorldApplet extends java.applet.Appple
{
public void init(){
resize( 200 , 150 );
}
public void paint( Graphics g){
g.drawString("Hello World" , 50 , 100);
}
}
C++ Code Example:
#include
class Hello :public Applet
{
public void init();
public void paint(Graphics g);
};
Hello::init()
{
resize( 200 , 150 );
}
......
我們看到,java開始就要求寫函數(shù)的實現(xiàn)。而C++先要描述輪廓。再
寫函數(shù)實現(xiàn)。
6.2. Java對從一般到特殊的思維方法支持的不好
從一般到特殊,是重要的思維方法。對應(yīng)到計算機學(xué)科就是繼承。而
今多繼承的概念已經(jīng)廣為流傳。比如我們說“小花貓”,就是繼承“
小”、“花”、“貓”三個概念。如果在字典上看到小花貓這個詞,
它一定不再描述“小”、“花”、“貓”這三個概念,而是繼承他們
。但是java只能繼承其中的一個。對另外連個還要仔細的描述。寫起
來是不是很煩。
6.3. Java設(shè)計不尊重“任何事物都有產(chǎn)生、發(fā)展、消亡的過程”這
一自然規(guī)律
Java沒有析構(gòu)函數(shù)。這一點很討厭。我只想重復(fù)一遍“對象不都在內(nèi)
存空間中”。
6.4. Java 不能表達少數(shù)類之間的緊密相關(guān)
java要求每個類使用一個文件。這種實現(xiàn)可能和它的自動編譯執(zhí)行方
式有關(guān)。注意這種限制不是實現(xiàn)上問題,而是規(guī)范中的語句。但是這
種方法合適嗎?請看下面C++的例子。將這兩個類分開為兩個文件是
否真的好讀?
struct menuitem{
String strX;
int iIndex;
};
class menu{
menuitem item[100];
... ...
};
和這種情況類似,javadoc也不能對緊密相關(guān)的數(shù)據(jù)進行描述。
至于類模板。java更是不支持。自己一個一個的慢慢寫吧。
6.5. 批判Java的批判
Java要誕生,必須批判原有C/C++語言的缺陷。列舉其中一二。
“C/C++語言中的整形數(shù)據(jù)不限制長度。這樣一來當程序從32位系統(tǒng)
移植到16 位系統(tǒng)時會造成錯誤”?墒亲屑毾胂搿_@種移植的概率
究竟有多少?
“Java不像C/C++,它完全不支持指針”。按此理論,同樣不支持指
針的Fortran77和basic是不是也很強壯。
“Java不允許隱式類型轉(zhuǎn)換”。如果整形和浮點數(shù)據(jù)之間的轉(zhuǎn)換都要
寫一下,是不是很煩。
“聯(lián)合體、全局變量他們都不是面向?qū)ο蟮臇|西”。面向?qū)ο笠恢本?
沒有什么定義。本著好用的東西就是好東西的原則,保留這些概念也
不錯。像M_PI這類的常量或者項目中的確全局相關(guān)的準常量,使用全
局變量是不是很方便?至于聯(lián)合體,是優(yōu)化存儲效率用的,像 Java
這種不考慮效率的語言自然不會支持。
“java存在比C++多的運算符”。好像是多一些,他們是(字符串 +),
> >> , (boolean)& and , instanceof。但是我們分析一下。由
于java不支持運算符重載,只好單獨實現(xiàn)(字符串 +)。由于java 不
區(qū)分有符號和無符號數(shù)據(jù),所以使用>>>來表達無符號右移、由于jav
a中的boolean和整形之間沒有聯(lián)系,又不支持運算符重載,所以對bo
olean類型單獨實現(xiàn)& and 。至于instanceof的確是Java 獨創(chuàng),不
過這個運算符的用處還要考慮。我在引用某變量時居然能不知道它的
類型?
6.6. 兼容以不兼容為代價
使用java 必須一切從頭開始。java不能繼承原有的工作。而且它也
不能很好的和其他語言混合編程。這就和C++區(qū)別大了。首先C++繼承
了大部分C語言代碼。其次,C++可以和Pascal , Fortran , Basic,
T-SQL等其他語言方便混合。尤其方便的是ASM語言和 C++混合。發(fā)揮
不同語言的長處。俗話說“朋友多,天地寬”嗎。而 java只能孤軍
奮戰(zhàn)了。
7. 結(jié)束語
寫這篇文章用了一天半的時間。又在Java上花了這么多時間,真是心
痛。但愿有些效果。
7/7