簡體   English   中英

使用NON靜態類方法無需參考

[英]Using NON static class Methods Without reference

我是Java的新手。 我知道靜態和非靜態方法的概念。 我想知道是否可以使用類的非靜態方法而不必創建對它的引用。

例如,對於我的程序,我正在使用Date對象,我需要在其中一個中獲取昨天的日期。 我知道一種可能的方式如下:

Calendar  cal=  Calendar.getInstance();
cal.add(Calendar.DATE,-1);
Date yesterdayDate = new Date();
yesterdayDate = cal.getTime();

有沒有辦法做到這一點,而不必創建我將在整個程序中只使用一次的cal引用?

像這樣的東西(我知道這絕不是一個正確的語法):

Date yesterdayDate = new Date();

yesterdayDate = Calendar.getInstance().add(Calendar.DATE,-1).getTime();

如果Calendar遵循一個流暢的構建器模式,即add方法正在添加,那么返回變異的實例,您將能夠。

你沒有,因為Calendar#add返回void

但不要被愚弄: Calendar.getInstance() 確實按照指示創建了一個實例 - 你只是沒有將它分配給引用。

你所指的是已知的Builder模式。

不構建Calendar類以支持構建器模式,但是還有許多其他類/ apis。

例如,joda時間的DateTimeFormatterBuilder

DateTimeFormatter monthAndYear = new DateTimeFormatterBuilder()
    .appendMonthOfYearText()
    .appendLiteral(' ')
    .appendYear(4, 4)
    .toFormatter();

您可以隨時繼續創建自己的構建器。 (在您的示例中, CalendarBuilder )。

但是你應該知道Calendar類通常被認為是邪惡的 - 它不是線程安全的。 更新的替代品是joda時間和java 8 api。

如果方法返回類型是任何類的實例,則應該對其進行鏈接調用,而不需要創建命名變量。

這在Fluent接口api中使用,其中每個方法都返回“this”類的實例。

注意:如果在不同的對象上調用許多鏈式方法,請注意:

collection.get(0).getAddress()getStreet()長度()。;

因為可能有NullPointerExceptions。

另一方面,使用流暢的api應該是安全的,因為你總是在“this”實例上調用它,所以如果api沒有一些奇怪的錯誤,它是安全的,NPE不應該發生。

其他答案都是正確的,但我認為他們錯過了一個關鍵點:如果你是Java的新手......不要浪費你的時間思考這些問題。

不要誤會我的意思:理解你正在使用的編程語言總是很好; 並且有一些常識來避免“真正愚蠢的表現”錯誤也很重要。

但是:不要擔心“性能”並花費數小時來減少程序處理的對象數量......從100到95.這完全是浪費時間。

如果你打算編寫使用時間較長的程序,並且由多個人編寫(而“好的”程序往往會很快到達那里),那么你的程序易於閱讀,理解就更重要了,並改變。

研究“績效”的唯一正當理由是:

  1. 你正處於設計階段; 如前所述,應避免因性能問題導致最終產品“無法使用”的愚蠢錯誤。
  2. 你實際上遇到了“性能”問題。 然后你應該開始分析你的應用程序; 然后,基於該分析改善“慢”部分。

換句話說:不要試圖解決“不存在”的問題。 除非您的應用程序在嵌入式環境中運行,其中每個內存字節和每個CPU周期都可以獲得特定獎勵...不要擔心創建這些Calendar對象10,100或500次。

一般的答案是否定的,因為像Calendar這樣的類是有狀態的,因此需要初始化的實例才能運行。 如果你這樣做:

Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE,-1);

您首先調用工廠方法getInstance()來創建GregorianCalendar的實例,這是Calendar的默認具體實現。 它被初始化為默認時區和語言環境,並設置為當前系統時間。 這意味着它與您在幾毫秒后創建的另一個實例不同。

然后,在您的實例上調用add(...)或其他操作方法會影響日歷狀態,遵循編程的日歷邏輯。 如果這不是離散實例而是全局(靜態)狀態,則多個線程會相互干擾並導致非常混亂的結果。

例如,SimpleDateFormat類也是如此。 它通常被錯誤地設置為字段並重新用於在多線程上下文中格式化日期(例如,servlet的handle方法)。 這將導致不穩定的行為,因為SimpleDateFormat也是有狀態的。

所以結論是:你需要創建像Calendar和SimpleDateFormat這樣的類的獨立實例,因為它們是有狀態的,因此不是線程安全的。

請記住,有時您可以通過在執行任何迭代之前聲明實例來優化一點,然后重新設置其狀態,而不是在每次迭代時創建新實例(畢竟,創建Calendar的實例確實有點昂貴)。

這不僅僅是因為方法不是靜態的。 明白你不能這樣鏈 - yesterdayDate = Calendar.getInstance().add(Calendar.DATE,-1).getTime(); 因為add()方法不返回任何內容。 如果該方法會返回相同的日歷對象,則可以在不創建引用的情況下鏈接它們。

只是為了理解鏈接是如何工作的,你可以嘗試創建自己的方法,返回對象並調用其他方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM