三種很難學到的Java踩坑教訓 - Miloš
學習Java很難。經驗是最好的老師。經驗教你克服錯誤。我從錯誤中吸取了教訓。你可以從我的錯誤中吸取教訓。
這是我透過艱苦的方式學到的東西,而您不必這樣做。
1. Lambdas 可能會給你帶來困難
Lambda通常超過 4 行程式碼。做的比應該做的多。更多的責任——你的工作記憶更難。更多行——多重責任 lambda。
您是否需要更改 lambda 中的變數? 你不能那樣做。 為什麼?如果 lambda 可以訪問呼叫跨界變數,則可能會出現多執行緒問題。您不能從 lambda 內部更改呼叫變數。
lambda 中的快樂路徑效果很好。執行時崩潰後,您會收到以下響應:
at [CLASS].lambda$null$2([CLASS].java:85) at [CLASS]$$Lambda$64/730559617.accept(Unknown Source) |
Lambda 堆疊跟蹤令人痛苦。名稱被混淆、難以跟蹤且難以除錯。
除錯 lambda 的更好方法是什麼? 使用中間結果。
map(elem -> { int result = elem.getResult(); return result; }); |
更好的方法是使用高階 IntelliJ 除錯技巧。使用TAB來選擇要除錯的程式碼。將此與中間結果相結合以獲得更好的體驗。
“當我們在包含 lambda 的行處停止時,如果我們按 F7(步入),那麼 IntelliJ 將突出顯示要除錯的程式碼段。我們可以使用 Tab 切換要除錯的塊,一旦我們決定,然後我們再次單擊 F7。”
如何從 lambda 訪問呼叫跨界變數? 您只能訪問 final 或有效的 final 變數。您需要包裝呼叫變數。無論是AtomicType或您自己的型別。您可以從 lambda 更改包裝的變數。
如何解決堆疊跟蹤問題? 使用命名函式。您現在可以找到負責任的程式碼、審查邏輯並更快地解決問題。使用命名函式來減少神秘的堆疊跟蹤。
相同的 lambda 重複? 把它放在一個命名函式中。您將有一個參考點。每個 lambda 都有一個生成的函式,這使得跟蹤變得更加困難。
lambda$yourNamedFunction lambda$0 |
命名函式解決了另一個問題。命名函式會劃分大lambdas,建立更小的程式碼塊,並建立可插入的函式。
.map(this::namedFunc1).filter(this::namedFilter1).map(this::namedFunc2) |
2. 你會遇到列表List問題
您需要使用 Lists。您需要 HashMaps 來獲取類似字典的資料。您需要 TreeMap 角色。您不可能不使用集合。
你如何構建一個列表?你需要什麼清單?你需要一個不可變或可變的列表嗎?答案會影響程式碼的未來。早點選擇正確的清單,否則就會受苦。
Arrays::asList建立“直寫”列表。你不能用這個列表做什麼?您無法更改已建立列表的大小。大小是不可變的。你可以做什麼?設定元素、排序或其他不影響大小的操作。Arrays::asList小心使用,因為它的大小是不可變的,但內容不是。
new ArrayList()建立一個新的“可變”列表。
建立的列表支援哪些操作?這就是要謹慎的原因。
List::of 建立一個“不可變的”集合。大小是不變的,但是內容在某些條件下是不可變的,如果內容是原始值,即 int,則列表是不可變的。看下面的例子。
@Test public void testListOfBuilders() { System.out.println("### TESTING listOF with mutable content ###"); StringBuilder one = new StringBuilder(); one.append("a"); StringBuilder two = new StringBuilder(); two.append("a"); List<StringBuilder> asList = List.of(one, two); asList.get(0).append("123"); System.out.println(asList.get(0).toString()); } 輸出: ### TESTING listOF with mutable content ### a123 |
您需要建立不可變物件並將它們放入List::of才能真正保證不可變, List::of不保證不變性。
3. 註釋讓你慢下來
你使用註解嗎?你瞭解他們嗎?你知道他們做什麼嗎?
自定義Logged註釋 是否適用於每種方法?錯誤的。我已經使用 ourLogged來記錄方法的引數。令我驚訝的是,它不起作用。您盲目地使用自定義註釋。
@Transaction @Method("GET") @PathElement("time") @PathElement("date") @Autowired @Secure("ROLE_ADMIN") public void manage(@Qualifier('time')int time) { ... } |
這段程式碼有什麼不愉快的地方?有很多配置摘要。你會經常遇到這種情況。配置與常規程式碼混合在一起。本身還不錯,但很難看。
註釋是有代價的。讀者為閱讀付出的代價。我們為了更快的開發而交易冗長。
註釋是為了減少樣板程式碼。您不需要為每個端點編寫日誌邏輯。您不需要配置事務,使用@Transactional. 註釋透過提取程式碼來減少樣板。
好的,我們應該回到 XML 嗎?不。我正在使用基於 Spring 的應用程式,並且使用 XML 進行配置是輕而易舉的。我們確實有註釋,但大部分配置都是在XML 中。模式指導配置,學習曲線並不陡峭。註釋很方便。註釋優勢在於方便,XML 優勢在於冗長。
這裡沒有明確的贏家,因為兩者都在發揮作用。直到今天,我仍然使用 XML 和註釋。當您發現重複的樣板檔案時,最好將註釋背後的邏輯移動。例如,日誌記錄是一個很好的註釋候選者。這個故事的寓意是:不要濫用註釋,不要忘記 XML
相關文章
- Docker踩坑四個教訓 - resurfaceDocker
- 【血淚教訓】godaddy競拍域名踩過的坑Go
- PWA踩坑記,手把手教學vue搭建PWAVue
- 教妹學 Java:晦澀難懂的泛型Java泛型
- 教妹學 Java:難以駕馭的多執行緒Java執行緒
- django專案部署到centos,踩的坑DjangoCentOS
- 基於合作教學的幾種教學方法
- 程式設計師生涯,學到最重要的6個教訓程式設計師
- 我的學習(踩坑)記錄
- Android、Java RSA加密踩坑記AndroidJava加密
- php學習踩坑(一)PHP
- 使用Go兩年學到的五大經驗教訓 - hashnodeGo
- 搭建容易維護難!谷歌機器學習系統血淚教訓谷歌機器學習
- 滾動到頂部踩坑記錄
- golang的踩坑Golang
- Java Agent 踩坑之 appendToSystemClassLoaderSearch 問題JavaAPP
- 2024年暑期教師研修快速學習方法(三種)
- Python 初學者容易踩的 5 個坑Python
- java踩坑之java.io.IOException: No space left on deviceJavaExceptiondev
- 5年程式設計師生涯,我學到最重要的6個教訓程式設計師
- # Laravel 5.5 升級到 6.0 踩坑記錄Laravel
- AS上傳Library到JCenter 教程+踩坑記錄
- Java踩坑記系列之Arrays.AsListJava
- 成都0基礎java培訓難不難Java
- 學習3D建模很難嗎,是不是很辛苦?3D
- 新手學習laravel踩坑記錄Laravel
- mybatis學習與踩坑記錄MyBatis
- GeoServer 踩過的坑Server
- Java中String.format變得更快 - MilošJavaORM
- 參加java培訓真的能學到有用的嗎Java
- 避坑手冊 | JAVA編碼中容易踩坑的十大陷阱Java
- Java開發者使用C++寫程式踩的坑JavaC++
- protodep踩坑
- Flutter 踩坑Flutter
- angular踩坑Angular
- CDH踩坑
- vue踩坑Vue
- 相容踩坑