溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何寫出更好的Java代碼

發(fā)布時(shí)間:2020-07-12 10:31:36 來源:網(wǎng)絡(luò) 閱讀:178 作者:sxt程序猿 欄目:編程語言

編碼風(fēng)格

傳統(tǒng)的Java編碼方式是非常啰嗦的企業(yè)級JavaBean的風(fēng)格。新的風(fēng)格更簡潔準(zhǔn)確,對眼睛也更好。

結(jié)構(gòu)體

我們這些碼農(nóng)干的最簡單的事情就是傳遞數(shù)據(jù)了。傳統(tǒng)的方式就是定義一個(gè)JavaBean:

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">public class DataHolder {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsppublic final String data;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"><br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsppublic DataHolder(String data) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbspthis.data = data;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp}<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">} nbsp </code>

這不僅拖沓而且浪費(fèi)。盡管你的IDE可以自動(dòng)地生成這個(gè),但這還是浪費(fèi)。因此,不要這么寫。

相反的,我更喜歡C的結(jié)構(gòu)體的風(fēng)格,寫出來的類只是包裝數(shù)據(jù):

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">public class DataHolder {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public final String data;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public DataHolder(String data) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp this.data = data;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">}</code>

這樣寫減少了一半的代碼。不僅如此,除非你繼承它,不然這個(gè)類是不可變的,由于它是不可變的,因此推斷它的值就簡單多了。

如果你存儲(chǔ)的是Map或者List這些可以容易被修改的數(shù)據(jù),你可以使用ImmutableMap或者ImmutableList,這個(gè)在不可變性這節(jié)中會(huì)有討論。

Builder模式

如果你有一個(gè)相對復(fù)雜的對象,可以考慮下Builder模式。

你在對象里邊創(chuàng)建一個(gè)子類,用來構(gòu)造你的這個(gè)對象。它使用的是可修改的狀態(tài),但一旦你調(diào)用了build方法,它會(huì)生成一個(gè)不可變對象。

想象一下我們有一個(gè)非常復(fù)雜的對象DataHolder。它的構(gòu)造器看起來應(yīng)該是這樣的:

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">public class ComplicatedDataHolder {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public final String data;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public final int num;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp // lots more fields and a constructor<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public class Builder {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp private String data;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp private int num;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public Builder data(String data) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp this.data = data;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp return this;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public Builder num(int num) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp this.num = num;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp return this;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public ComplicatedDataHolder build() {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp return new ComplicatedDataHolder(data, num);<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp // etc<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp } <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">}</code>

現(xiàn)在你可以使用它了:

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">final ComplicatedDataHolder <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">cdh = new ComplicatedDataHolder.Builder()<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp .data("set this")<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp .num(523)<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp .build();</code>

關(guān)于Builder的使用這里還有些更好的例子,我這里舉的例子只是想讓你大概感受一下。當(dāng)然這會(huì)產(chǎn)生許多我們希望避免的樣板代碼,不過好處就是你有了一個(gè)不可變對象以及一個(gè)連貫接口。

依賴注入

這更像是一個(gè)軟件工程的章節(jié)而不是Java的,寫出可測的軟件的一個(gè)最佳方式就是使用依賴注入(Dependency injection,DI)。由于Java強(qiáng)烈鼓勵(lì)使用面向?qū)ο笤O(shè)計(jì) ,因此想寫出可測性強(qiáng)的軟件,你需要使用DI。

在Java中,這個(gè)通常都是用Spring框架來完成的。它有一個(gè)基于XML配置的綁定方式,并且仍然相當(dāng)流行。

重要的一點(diǎn)是你不要因?yàn)樗幕赬ML的配置格式而過度使用它了。在XML中應(yīng)該沒有任何的邏輯和控制結(jié)構(gòu)。它只應(yīng)該是依賴注入。

還有一個(gè)不錯(cuò)的方式是使用Dagger庫以及Google的Guice。它們并沒有使用Spring的XML配置文件的格式,而是將注入的邏輯放到了注解和代碼里。

避免null值

如果有可能的話盡量避免使用null值。你可以返回一個(gè)空的集合,但不要返回null集合。如果你準(zhǔn)備使用null的話,考慮一下@Nullable注解。IntelliJ IDEA對于@Nullable注解有內(nèi)建的支持。

如果你使用的是Java 8的話,可以考慮下新的Optional類型。如果一個(gè)值可能存在也可能不存在,把它封裝到Optional類里面,就像這樣:

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">public class FooWidget {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp private final String data;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp private final OptionalltBargt bar;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp public FooWidget(String data) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp nbsp nbsp this(data, Optional.empty());<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp public FooWidget(String data, OptionalltBargt bar) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp nbsp nbsp this.data = data;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp nbsp nbsp this.bar = bar;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp public OptionalltBargt getBar() {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp nbsp nbsp return bar;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">}</code>

現(xiàn)在問題就清楚了,data是不會(huì)為null的,而bar可能為空。Optional類有一些像isPresent這樣的方法,這讓它感覺跟檢查null沒什么區(qū)別。

不過有了它你可以寫出這樣的語句:

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">final OptionalltFooWidgetgt <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">fooWidget = maybeGetFooWidget(); <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">final Baz baz = fooWidget.flatMap(FooWidget::getBar)<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp.flatMap(BarWidget::getBaz)<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp.orElse(defaultBaz); nbsp </code>

這比使用if來檢查null好多了。唯一的缺點(diǎn)就是標(biāo)準(zhǔn)類庫中對Optional的支持并不是很好,因此你還是需要對null進(jìn)行檢查的。

不可變

變量,類,集合,這些都應(yīng)該是不可變的,除非你有更好的理由它們的確需要進(jìn)行修改。

變量可以通過final來設(shè)置成不可變的:

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">final FooWidget fooWidget;<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbspif (condition()) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbspfooWidget = getWidget();<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp} else {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsptry {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp nbsp nbspfooWidget = cachedFooWidget.get();<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp} catch (CachingException e) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp nbsp nbsplog.error("Couldn't get cached value", e);<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp nbsp nbspthrow e; nbsp<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp} <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp } // fooWidget is guaranteed to be set here nbsp </code>

現(xiàn)在你可以確認(rèn)fooWidget不會(huì)不小心被重新賦值了。final關(guān)鍵字可以和if/else塊以及try/catch塊配合使用。當(dāng)然了,如果fooWidget對象不是不可變的,你也可以很容易地對它進(jìn)行修改。

有可能的話,集合都應(yīng)該盡量使用Guava的ImmutableMap, ImmutableList, or ImmutableSet類。這些類都有自己的構(gòu)造器,你可以動(dòng)態(tài)的創(chuàng)建它們,然后將它們設(shè)置成不可變的。

要使一個(gè)類不可變,你可以將它的字段聲明成不可變的(設(shè)置成final)。你也可以把類自身也設(shè)置成final的這樣它就不能被擴(kuò)展并且修改了,當(dāng)然這是可選的。

避免大量的工具類

如果你發(fā)現(xiàn)自己添加了許多方法到一個(gè)Util類里,你要注意了。

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">public class MiscUtil {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public static String frobnicateString(String base, int times) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp // ... etc<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public static void throwIfCondition(boolean condition, String msg) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp // ... etc<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">}</code>

這些類乍一看挺吸引人的,因?yàn)樗鼈兝锩娴倪@些方法不屬于任何一個(gè)地方。因此你以代碼重用之名將它們?nèi)既拥竭@里了。

這么解決問題結(jié)果更糟。把它們放回它們原本屬于的地方吧,如果你確實(shí)有一些類似的常用方法,考慮下Java 8里接口的默認(rèn)方法。并且由于它們是接口,你可以實(shí)現(xiàn)多個(gè)方法。

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">public interface Thrower {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public void throwIfCondition(boolean condition, String msg) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp // ... nbsp nbsp<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp } nbsp nbsp<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp public void throwAorB(Throwable a, Throwable b, boolean throwA) { nbsp <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp // ... nbsp <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> }</code>

這樣需要使用它的類只需簡單的實(shí)現(xiàn)下這個(gè)接口就可以了。

格式

格式遠(yuǎn)比許多程序員相像的要重要的多。一致的格式說明你關(guān)注自己的代碼或者對別人有所幫助?

是的。不過你先不要著急為了讓代碼整齊點(diǎn)而浪費(fèi)一整天的時(shí)間在那給if塊加空格了。

如果你確實(shí)需要一份代碼格式規(guī)范,我強(qiáng)烈推薦Google的Java風(fēng)格指南。這份指南最精彩的部分就是編程實(shí)踐這節(jié)了。非常值得一讀。

文檔

面向用戶的代碼編寫下文檔還是很重要的。這意味著你需要提供一些使用的示例,同時(shí)你的變量方法和類名都應(yīng)該有適當(dāng)?shù)拿枋鲂畔ⅰ?/p>

結(jié)論就是不要給不需要文檔的地方添加文檔。如果對于某個(gè)參數(shù)你沒什么可說的,或者它已經(jīng)非常明顯了,別寫文檔了。模板化的文檔比沒有文檔更糟糕,因?yàn)樗垓_了你的用戶,讓他覺得這里有文檔。

Java 8有一個(gè)漂亮的流和lambda表達(dá)式的語法。你的代碼可以這么寫:

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">final ListltStringgt <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">filtered = list.stream()<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp .filter(s -gt s.startsWith("s")) nbsp nbsp<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp .map(s -gt s.toUpperCase()); </code>

而不是這樣:

<code style="margin: 0px; padding: 0px; max-width: 100%; font-family: Fixedsys; color: rgb(51, 51, 51); background-color: rgb(248, 248, 248); box-sizing: border-box !important; overflow-wrap: break-word !important;">final ListltStringgt <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">filtered = Lists.newArrayList(); <br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">for (String str : list) {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp if (str.startsWith("s") {<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp nbsp nbsp filtered.add(str.toUpperCase());<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;"> nbsp nbsp }<br data-filtered="filtered" style="line-height: normal; margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">}</code>

這樣你能寫出更連貫的代碼,可讀性也更強(qiáng)。

部署

正確地部署Java程序還是需要點(diǎn)技巧的。現(xiàn)在部署Java代碼的主流方式有兩種 :使用框架或者使用自家摸索出來的解決方案,當(dāng)然那樣更靈活。

框架

由于部署Java程序并不容易,因此才有了各種框架來用于部署。最好的兩個(gè)是Dropwizard以及Spring Boot。Play Framework也可以算是一個(gè)部署框架。

這些框架都試圖降低部署程序的門檻。如果你是一個(gè)Java的新手或者你需要快速把事情搞定的話,那么框架就派上用場了。單個(gè)jar的部署當(dāng)然會(huì)比復(fù)雜的WAR或者EAR部署要更容易一些。

然而,這些框架的靈活性不夠,并且相當(dāng)頑固,因此如果這些框架的開發(fā)人員給出的方式不太適合你的項(xiàng)目的話,你只能自己進(jìn)行配置了。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI