簡體   English   中英

Java:設置對象創建時間

[英]Java: Setting time of object creation

Java新手問題。 我想低估可能設置和存儲對象創建時間的原則。

碼:

包:

package com.Test;

public class Test_package {

    private static int hour;
    private static int minute;
    private static int second;


    public Test_package(){
        this.hour = (int)(((System.currentTimeMillis()/1000) /60) / 60) % 24 + 3;
        this.minute = (int)((System.currentTimeMillis() / 1000) /60 ) % 60;
        this.second =(int)(System.currentTimeMillis() /1000) % 60;      
    }

    public void getTime(){
        System.out.println("Stundas:" + this.hour +" minute: " +this.minute + " sekunde:"+ this.second);
    }
}

主類:

import com.Test.*;
public class Test {

    public static void main(String[] args) {

        Test_package objectTime = new Test_package();

        objectTime.getTime();
    }
}

我得到的是當前時間,這很好,但是我想了解創建對象時的原理,設置了對象創建的時間,所以當我調用方法.getTime()時,我得到了對象的時間不是當前時間創建的。

換句話說,我該如何存儲時間。 還是我的代碼可以,但是由於主類一遍又一遍地重新執行而無法創建所需的結果,因此我無法看到所需的結果。

您的編碼完成了99%。 雖然有一些問題。

1)為了使自己相信自己正在顯示創建時間,而不僅僅是在調用getTime()之前先休眠一下

Test_package objectTime = new Test_package();
Thread.sleep(300000); // sleep 5 mins
objectTime.getTime();

2)構造函數多次調用getCurrentTime; 在大多數情況下,這會很好,但是如果系統在錯誤的時刻進行呼叫,則可能會浪費時間標記。 考慮到通話的數量,這只會在每分鍾結束時出現問題,就像時鍾將要倒計時一樣。 要解決此問題,請一次調用System.currentTimeMillis並重用該值。

public Test_package(){
    long nowMillis = System.currentTimeMillis();

    this.hour = (int)(((nowMillis/1000) /60) / 60) % 24 + 3;
    this.minute = (int)((nowMillis / 1000) /60 ) % 60;
    this.second =(int)(nowMillis /1000) % 60;      
}

3)您正在重用相同的變量,因此,如果創建了多個對象,則僅會存儲最后一個對象的時間戳。 要解決此問題,請從小時,分鍾和秒的每個字段中刪除關鍵字static。

4)您已將UTC的時區硬編碼為+3,這對您來說可能不是問題,但值得引起注意。 這樣做的通常方法是只將millis存儲為一個字段,然后使用時間格式化程序進行打印,也許新的Date(millis).toString()就足夠了,它將使用平台的默認時區。

5)您還應該注意,currentTimeMillis的增量可能會大於1,從而報告在同一時間戳創建的對象比實際更多。 這取決於您所運行的操作系統,並且您幾乎無法控制。 在System上有一個單獨的調用,該調用返回相對的納秒計數並具有更精細的粒度,但是該調用不會給出絕對的時間,因此無法滿足您的要求。 我純粹是出於同情。

您的代碼基本上可以。

public class Test {

    public static void main(String[] args) throws Exception {

        Test_package objectTime = new Test_package();
        Thread.sleep(300000); // sleep 5 mins
        objectTime.getTime();
    }

}

嘗試以上。

您的主要“問題”只是調用getTime()
在創建對象之后。 嘗試在兩者之間睡覺。
然后getTime將打印5分鍾前的時間,而不是
當前時間。

由於您的時間變量是static ,因此每個變量只有一個實例,因此,如果您創建多個對象並從任何一個(或從類)獲取時間,則將獲得最后一個對象的創建時間。

也許這就是您想要的,否則,只需從這些變量中刪除static關鍵字即可。

您不想使用靜態字段,否則將最終保存創建的最后一個對象,而不是保存每個對象的創建時間。 另外,您只需要以毫秒為單位存儲時間。

package com.Test;
public class Test_package {

    private final Date created = new Date();

    public void getTime() {
        SimpleDateFormat sdf = new SimpleDateFormat(
                                   "'Stundas:'HH' minute: 'mm' sekunde:'ss");
        System.out.println(sdf.format(created));
    }
}

static

由於其他正確答案的狀態,您不應對單個對象(實例)使用static方法。

“靜態”一詞在C和Java中有着悠久而曲折的歷史,我們可以忽略。 結果是,在Java中,“靜態”一詞的意思是“不是面向對象的”。 “靜態”一詞意味着我們希望在整個工作會話中僅在內存中保留一些數據(“狀態”)一次。 沒有更好的保留位置,我們將數據粘貼到類在內存中的表示形式。 使用普通的面向對象的非靜態成員變量,每個對象(實例)都有自己的數據。 對於Person對象,每個Person對象都有其自己的firstNamephoneNumber值,而Person類上的靜態變量在內存周期中將只有一個值。

具有非OOP語言背景的程序員可能會被吸引到static變量,因為它們看起來像全局變量。 確實,您可以使用類似於非OOP語言的代碼成功地完全用靜態變量和靜態方法制作Java程序。 但是您會錯過OOP帶來的強大功能和簡單性。

看到問題, “ static”關鍵字在類中做什么?

日期時間類型

通常,在處理日期時間數據時最好使用日期時間數據類型。 以毫秒為單位的跟蹤時間(從epoch開始計數)很快變得笨拙,混亂並且難以調試。 而且,日期時間工作令人驚訝地復雜且棘手。 只需在StackOverflow.com上搜索java date即可查看日期時間變得多么復雜。

例如,您的Question的代碼錯誤地將System.currentTimeMillis視為一天中的時間,而實際上它是從UTC時區的1970年第一時刻開始計算的,因此它是日期一天中的時間。

您不會將數字作為位或文本作為八位字節處理; 我們已經將類定義為數據類型,以處理和隱藏細節。 因此,您應該使用日期時間類而不是count-since-epoch。

日期時間庫

對於Java,我們有兩個很好的日期時間庫:

兩者都有優勢。 幸運的是,您可以混合使用這兩種方式,並且更適合特定情況。

Java還具有一些用於日期時間工作的較舊的類,java.util.Date,java.util.Calendar,java.text.SimpleDateFormat和其他一些類(均在java.time包之外)。 不幸的是,這些類非常麻煩,具有令人困惑的歷史和發展,以及設計和實現方面的問題。 避免他們。 它們已被java.time取代。 在需要的地方,您可以與Joda-Time以及java.time相互轉換。

物體死

main方法的最后,您的Java程序結束了。 內存中的所有數據均已清除,消失。 因此,如果您想長時間存儲該數據,則必須將其持久化。 也許編寫文件,或將其放入數據庫。

在您的Question的代碼和下面的示例中,每次執行/運行程序時,都會從頭開始重新創建對象。 因此,每個對象都有一個新的日期時間。

范例程式碼

這是Joda-Time 2.4中的一些示例代碼。

我們有一個“動物”類,該類跟蹤其對象被實例化的時間(在運行時,分配了一塊內存來存儲其數據)。 該時刻記錄在Joda-Time庫中定義的DateTime類型的成員變量“ objectCreation”中。

分配的時區不是隱式依賴於JVM的當前默認時區。 在這種情況下,我會從適當的時區名稱列表中任意選擇內羅畢。

作為使用static的示例,我創建了三個常量,定義了預期的種類。 這是一個實際的示例,在該示例中,我們避免並檢測到“ dog”之類的錯字,例如“ dg”。

本示例捕獲執行的開始和結束時間以顯示時間跨度。

package com.example.yourpackage;

import java.util.concurrent.TimeUnit;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Interval;
import org.joda.time.Period;

public class Animal
{
    // Static vars exist once in memory, and can be accessed by *any* Animal object (or other objects).
    static final String SPECIES_DOG = "dog";
    static final String SPECIES_CAT = "cat";
    static final String SPECIES_BIRD = "bird";

    // Each instance (each Animal object) has its own value for each of these member variables.
    DateTime objectCreation = null;
    String species = null;
    String name = null;

    // Constructor method.
    public Animal( String speciesArg , String nameArg )
    {
        if ( ( speciesArg.equals( Animal.SPECIES_DOG ) ) || ( speciesArg.equals( Animal.SPECIES_CAT ) ) || ( speciesArg.equals( Animal.SPECIES_BIRD ) ) ) {
            // If we were passed an expected species, proceed.
            this.objectCreation = DateTime.now( DateTimeZone.forID( "Africa/Nairobi" ) ); // Or DateTimeZone.UTC
            this.species = speciesArg;
            this.name = nameArg;
        } else {
            // Else we were passed an unexpected species.
            // FIXME: Handle this error condition…
        }
    }

    @Override
    public String toString()
    {
        return "Animal{" + "objectCreation=" + objectCreation + ", species=" + species + ", name=" + name + '}';
    }

    public static void main( String[] args )
    {
        DateTime start = DateTime.now( DateTimeZone.forID( "Africa/Nairobi" ) );

        Animal x = new Animal( "dog" , "Buddy" );
        try {
            TimeUnit.SECONDS.sleep( 3 );
        } catch ( InterruptedException ex ) {
            System.out.println( "Exception: " + ex );  // FIXME: Handle this error condition…
        }

        Animal y = new Animal( "dog" , "Rover" );
        try {
            TimeUnit.SECONDS.sleep( 5 );
        } catch ( InterruptedException ex ) {
            System.out.println( "Exception: " + ex );  // FIXME: Handle this error condition…
        }

        Animal z = new Animal( "bird" , "Polly" );

        DateTime stop = DateTime.now( DateTimeZone.forID( "Africa/Nairobi" ) );
        Interval interval = new Interval( start , stop );
        Period period = interval.toPeriod();

        System.out.println( "x: " + x );
        System.out.println( "y: " + y );
        System.out.println( "z: " + z );
        System.out.println( "Interval: " + interval + "  Period: " + period );
    }

}

運行時。

x: Animal{objectCreation=2014-09-16T10:17:00.636+03:00, species=dog, name=Buddy}
y: Animal{objectCreation=2014-09-16T10:17:03.635+03:00, species=dog, name=Rover}
z: Animal{objectCreation=2014-09-16T10:17:08.634+03:00, species=bird, name=Polly}
Interval: 2014-09-16T10:17:00.575+03:00/2014-09-16T10:17:08.634+03:00  Period: PT8.059S

命名

提示:建議您在命名類時避免一般使用“包”一詞。 單詞package是用於定義類的關鍵字,如您的Question代碼的第一行所示。 因此,將“包”混入類名中會造成混淆。

暫無
暫無

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

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