为什么总是有人说Java啰嗦,却没人说C++啰嗦?
因為Java只支持面向對象一種編程范式。
只支持一種范式,好處是嚴謹,風格統(tǒng)一;壞處就是呆板、啰嗦。典型如它的main函數(shù),再也不能像別的語言那樣寫成一個獨立的函數(shù),而是必須包在一個沒有實際作用的類里面……
這樣“不管有沒有必要,反正你必須把任何東西都先弄成類”的要求,顯然會導致許多本無必要的間接訪問以及由此衍生的其他很多麻煩——和其他語言相比,當然就顯得過于啰嗦了。
尤其是早期,相關理論尚未成熟,再加上單一范式的限制,就使得它相對于早已成熟的其他語言,顯得表達能力過弱——有一個著名的吐槽,大意就是“之所以Java需要搞出那么多設計模式,就是因為它表達能力太弱,別的語言很簡單就能做到的事,它就必須通過設計模式才能拐彎抹角的辦到”(當然,這些主要還是面向過程和面向對象風格本身的區(qū)別,不能完全算是Java的缺陷)。
與之相反,C++是一種“多范式”語言,非結構化、結構化、面向對象、宏、模板……啥好用你就能得到啥——任何工作,你都有最簡化實現(xiàn)它的可能。但缺陷就是,再也沒人能“精通C++”——你可以拿它當C用,當Java用,當object-c用,玩模板黑魔法用……但最好別把它當C++用。不然真沒人hold得住它。
當年的Pascal也一樣:它僅支持結構化編程一種范式,這種純粹而“板正”的風格使得它成了當時最佳的“教學語言”,但是很少被用到實際項目中。而當年的C,它支持結構化編程,同時也允許你任意解釋內存數(shù)據(jù)。這就使得它得到了額外的許多靈活性,甚至到現(xiàn)在都還充滿了生命力。
當然,過去和現(xiàn)在情況還不太一樣。
過去的編輯器沒現(xiàn)在這么強大、智能;Pascal的“板正”沒能帶來教學時概念清晰之外的更多好處,反而因為單一范式的束縛讓人感覺礙手礙腳,自然不是C的對手。
但現(xiàn)代編輯器強大的語法提示功能給了程序員太大方便——“板正”的單一范式強類型語言的語法提示實在太好做太強大了,你甚至很難把語法錯誤留到后半拉花括號敲出來之前:付出一點點“格式化”的代價,換來這么大的好處……與之相反,過于靈活隨意的C++,它的語法提示可不是一般的難做。
別說200x年前后的“黑暗時代”,哪怕到現(xiàn)在,都還有不少主流編輯器沒辦法為C++代碼提供Java級別的語法提示(我知道現(xiàn)在做的比較好的語法提示,其原理相當于在后臺邊編譯邊提示[實際是解析語法樹]:而且這個編譯器還必須支持“半拉函數(shù)”的動態(tài)編譯,不然很難給出準確的輸入建議)。
——亦因此,當年就沒人能勸我加入VIM教:在下寫C++必用eclipse/VS之類重量級IDE,不然語法提示真沒法看(當然,這都是上個年代的老黃歷了?,F(xiàn)在已經(jīng)有很多編輯器可以給出高水平的C++語法提示了,甚至可以自動提示模板實例化后的正確參數(shù)類型。至于VIM,它很早也已經(jīng)可以配出基于語法的提示了;不過本人太懶,早年實驗幾次感覺效果不佳就再也沒用它寫過C++……)。類似的,由于編譯器發(fā)展水平所限,過去的Pascal語法“板正”,使得它需要付出很大的額外性能消耗(因為沒有辦法像C那樣讓程序員“抖機靈”);而現(xiàn)在的Java,卻因為自己的板正,給了字節(jié)碼編譯器以及即地編譯器大量的提示,使得它們得以完成深度優(yōu)化,從而得到了極佳的執(zhí)行效率……
時代不一樣,配套技術成熟度不一樣,很多東西就不一樣了??傊?#xff0c;沒有免費的午餐,諸多相關也不是一成不變的;每一種成功語言之所以成功,都有其道理。評論利弊須就事論事,這才不容易翻船……
C++ 啰嗦,只是吐槽 C++ 啰嗦的人很多早就不在 JAVA 領域,做 Java 的也聽不到。
就啰嗦而言 C++ 和 Java 各有千秋。
為什么吐槽 Java 的多,因為 Java 的 啰嗦很多時候影響到了業(yè)務實現(xiàn)。
如萬物皆對象,設個回調、new 個線程、main 個函數(shù),一個指針能搞定的問題非要扯上 class、 interface。滿頁的set /get 不煩嗎? 又比如多值返回,C++ 不支持,但用指針變相實現(xiàn)也很簡單,到了 Java 只能包個對象送回去。覺得有引用就夠了?寫個支持變量和函數(shù)綁定的逆波蘭試試。
Java 里這類麻煩無處不在。這些繁瑣已經(jīng)滲透到框架和庫的方方面面,躲都躲不掉。
加上很多參考的新語言出現(xiàn),開發(fā)者也意識到這類語言設計特點帶來的麻煩其實是沒必要也沒意義的。
C++ 的 include、頭文件和衍生的 .d 這些用法都遠比 Java 的 import 啰嗦。
C++ 工具鏈的使用和配置都比 Java 麻煩花樣多。五花八門的編譯工具,dsl 還要加上 shell、python、lua 腳本,一個個都比 ant maven 難學難用。
考慮跨平臺,還得了解各平臺各編譯器的參數(shù)、OS 環(huán)境變量、庫命名差異、路徑差異、宏。
這些方面 Java 比 C++ 簡潔很多。
語言本身 C++ 不啰嗦嗎?hpp/cpp來回切,函數(shù)的前置聲明這些也很煩。
指針釋放,RTTI,這些 Java 開箱即用的到 C++ 都得造輪子,string,map 這些 stl 提供的很多人會重新造一遍。和 Netty 比 C++ 到現(xiàn)在網(wǎng)絡編程這塊也沒個一統(tǒng)江湖的庫。
另外 C++ 開發(fā)者用第三方庫的態(tài)度和 Java 顯著不同,寫 C++ 的經(jīng)常可以摳別人幾千行代碼只為最后能少鏈一個外部依賴,平白多很多事(而且這種做法很多時候還是對的),寫 java 的可以只為用1個函數(shù)多加幾個鏈式依賴包也無所謂。
C++ 麻煩的部分像工具鏈、編譯、項目管理基本是一次性負擔,還都讓 SA 扛了。C++ 做業(yè)務因為 有指針、宏和靈活到變態(tài)的模板,自己的業(yè)務代碼抽象低寫的丑多半是自己的能力問題。復雜又通用的業(yè)務,要么個體戶大神填了坑,要么微軟們早封好了。每個業(yè)務域都有大量精短高效只能勉強看懂的代碼和精短高效壓根全看不懂的代碼,想吐槽下也很快就從“語言好爛”的憤慨變成“我好爛水好深”的感慨。加上還有游戲引擎和編譯器這兩類魔王級項目,你說你業(yè)務復雜幾百萬代碼 ,行摘兩段讓我們 diss 一下吧。
不是 C++ 不啰嗦,是 C++ 其他痛點和要操心的地方太多,啰嗦的那點事也就不顯眼了。加上語言靈活特性多,也容易靠優(yōu)秀的個體發(fā)揮掩蓋這個缺陷。
并且 C ++ 已經(jīng)是原教旨主義范疇的東西,和 VIM 一樣,很容易被懟“不是不好用,是你蠢不會用”,而且問題在于很可能還真是。
Java的啰嗦有兩個意思,1、在Java代碼中存在很多重復,然后又沒辦法去掉,這里暴露Java抽象能力不足的問題;2、Java的代碼很嚴謹,接口使用什么,很契合設計模式,經(jīng)常是做一件事情,要沐浴更衣,要繁文縟節(jié),要三請四請,九彎十八曲之后,才輪到正主兒正式登場演出。這是因為在Java是名詞的世界,而且類型嚴謹,所以才搞得這么麻煩。這兩個原因糾纏在一塊,就搞得Java的代碼沒法簡潔,在猿語中,Java是出了名的啰嗦。
C語言的抽象能力不如Java,但人家是弱類型,人肉類型管理,猿猴高興的話,隨便強制類型轉換,就直奔主題去了,Java的禮節(jié)規(guī)矩問題,在C猿中完全無法忍受,甚至,必要時還可以搞預處理,這可是節(jié)省代碼的重要手段,雖然很丑陋,但是很管用。很多C開源庫的代碼,很少體現(xiàn)類型的概念,實在也沒法體現(xiàn),玩的是心驚肉跳驚心動魄。而C#對類型要求也很嚴謹,但是C#的抽象能力比java高好幾個層次,又配套了很多貼心語法糖,基本上可以替換C宏的很多運用,用于精簡代碼,非常有效。C#的語法設計,似乎骨子里對代碼啰嗦很排斥,所有導致啰嗦的地方,都會想心設法搞新語法糖去掉。
而大C++,抽象能力比C#還高一大截,而必要時,猿猴完全可以罔顧類型安全,C語言能Cast的,C++也能隨便Cast,const也可以Cast掉,而且,由于C++的類型推導能力很厲害,預處理在C++下又煥發(fā)出第二春。C++代碼,如果猿猴高興,如果猿猴嘔心瀝血,基本上可以去掉代碼中所有的重復。更何況,相比于C++本身的復雜,代碼啰嗦只是微不足道的一個小問題。
Java就只支持一種范式一種風格,不管你多會用都得羅嗦。而且Java社區(qū)無框架不開發(fā)的風氣加重了Java羅嗦的印象,畢竟按J2EE的風格你Hello個World就得上Spring折騰半天配置了人家C/C++幾行代碼一句gcc完事呢。
C++抽象能力很強,有各種模板、TMP黑科技,惹急了還有宏,只要你想搞你可以把C++寫得很簡潔,羅不羅嗦是可選的,至于實現(xiàn)黑科技過程中你寫的那一大堆template啊SFINAE什么的,放進namespace detail里對外人來說它們就不存在了,畢竟一大坨detail這能叫羅嗦么,這是C++水平的證明
C++的語法更加復雜,只要靈活使用,確實可以大大簡化代碼,例如:
C++支持多繼承,可以方便的繼承多個類的方法。而Java實現(xiàn)類似的功能要使用接口,需要在每個子類實現(xiàn)每個接口方法,非常的啰嗦。
C++支持操作符重載,可以實現(xiàn)很多復雜功能。在Java中,類似的功能需要用函數(shù)來實現(xiàn),非常啰嗦。
C++支持宏定義,可以方便的實現(xiàn)非常復雜,方便,有用的代碼模板(并不推薦),而Java沒有類似的功能。
不過,這幾個語法特性雖然可以簡化代碼,但要謹慎使用。特別是宏定義,因為難以調試和維護,最好不要用來實現(xiàn)復雜的功能。
但是,Java也有很多方法來簡化代碼。
Java支持反射。使用反射,可以很容易的實現(xiàn)一些C++中實現(xiàn)起來很麻煩的功能。
Java中,可以使用annotation和反射來自動生成代碼,可以大大簡化編程。
∑編輯?|?Gemini
來源 |?西部游星
算法數(shù)學之美微信公眾號歡迎賜稿
稿件涉及數(shù)學、物理、算法、計算機、編程等相關領域,經(jīng)采用我們將奉上稿酬。
投稿郵箱:math_alg@163.com
總結
以上是生活随笔為你收集整理的为什么总是有人说Java啰嗦,却没人说C++啰嗦?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里达摩院发布2019年十大科技趋势
- 下一篇: 9个细节告诉你,达摩院过去一年做了啥