Java - 获取对象的现有时间

时间:2017-01-21 05:16:53

标签: java oop

我们说我创建了一个像这样的对象

Object obj = new Object();

现在我想知道对象存在多久,比如

System.out.println("Creating object");
Object obj = new Object();
//Print 0
System.out.println("The object has existed for (ms): " + getTime(obj));
Thread.sleep(1000);
//Print 1000
System.out.println("The object has existed for (ms): " + getTime(obj));

我该怎么办?任何帮助表示赞赏。

3 个答案:

答案 0 :(得分:4)

试试这段代码。 finalize()方法在object的destroy time中运行。如果对象进入最终化方法运行的垃圾收集器。在我的代码System.gc()中用于调用garbase收集器。这段代码很长。它只是为了理解目的。您可以自定义此代码。

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Thamira
 */
public class Demostra {

    public static void main(String[] args) {

        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

        System.out.println("Creating object :" + sdf.format(cal.getTime()));
        Object obj = new Object() {

            @Override
            protected void finalize() throws Throwable {
                Calendar cal = Calendar.getInstance();
                SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
                System.out.println("The object has removed for : " + sdf.format(cal.getTime()));

                super.finalize(); //To change body of generated methods, choose Tools | Templates.
            }

        };

        cal = Calendar.getInstance();
        sdf = new SimpleDateFormat("HH:mm:ss");

        System.out.println("The object has existed for : " + sdf.format(cal.getTime()));
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Demostra.class.getName()).log(Level.SEVERE, null, ex);
        }

        cal = Calendar.getInstance();
        sdf = new SimpleDateFormat("HH:mm:ss");

        System.out.println("The object has existed for  : " + sdf.format(cal.getTime()));

        obj = null;

        System.gc();
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Demostra.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

}

答案 1 :(得分:3)

没有自动方式来执行此操作,不存在getTime(obj)方法。执行此操作的唯一方法是自己编写代码以手动检索系统时间,通常在需要时通过System.currentTimeMillis()完成,然后减去由此获得的值以获得持续时间或时间差。

现在你可以创建一个你自己连接的类来获得这个功能,它获得自己的创建时间并将它存储在一个字段中,而不是有自己的方法来返回存在的持续时间,事实上这很容易要做的,它的实施将留给学生练习。

答案 2 :(得分:2)

TL;博士

Duration.between( objectBorn , Instant.now() )

java.time

answer by lakmal看起来是正确的,除了它使用现在遗留的麻烦的旧日期时间类,取而代之的是java.time类。

正如另一个答案所解释的那样,默认情况下,Java对象不会跟踪它们存在的时间。您必须添加自己的代码来跟踪他们的出生和年龄。

Instant

Instant类代表UTC中时间轴上的一个时刻,分辨率为nanoseconds(小数部分最多九(9)位)。

Instant instant = Instant.now();  // Current moment in UTC.

在Java 8中,current moment is captured精度为毫秒(或更粗糙的粒度,具体取决于您的计算机硬件时钟)。在Java 9及更高版本中,fresh implementation Clock将潜在精度提高到纳秒,具体取决于计算机硬件时钟的能力。要清楚,在Java 8 Java 9中,您可以表示具有高达纳秒分辨率的时刻;只有捕获当前时刻在Java 8中才有限。

Duration

Duration类代表一段时间。

这是一个完整的例子。

package javatimestuff;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;

/**
 *
 * @author Basil Bourque
 */
public class Life {

    private Instant objectBorn = null;

    // Constructor
    public Life () {
        this.objectBorn = Instant.now ();  // Capture the moment at birth of this object.
    }

    public Duration objectAgeAsDuration () {
        Duration d = Duration.between ( objectBorn , Instant.now () );
        return d;
    }

    public long objectAgeAsNanos () {
        Duration d = this.objectAgeAsDuration ();
        return d.toNanos ();
    }

}

练习那门课。

    public static void main ( String[] args ) {
        System.out.println ( "Please wait a few seconds as we birth a new `Life` object. " );

        Life l = new Life ();
        try {
            Thread.sleep ( TimeUnit.SECONDS.toMillis ( 3 ) );
        } catch ( InterruptedException ex ) {
            // Interruption may be this thread being woken.
            // …
        }

        System.out.println ( "The Life object’s age as Duration: " + l.objectAgeAsDuration () );
        System.out.println ( "The Life object’s age as nanoseconds: " + l.objectAgeAsNanos () );
    }
  

我们出生一个新的Life对象时,请等待几秒钟。

     

生命对象的年龄为持续时间:PT3.002S

     

Life对象的年龄为纳秒:3010000000

finalize无关紧要且不可靠

您的评论谈论想要获取对象的finalize方法运行的时间。在这方面你应该知道两件重要的事情:

  • finalize在对象成为垃圾回收的候选者之后发生 之后的。它可能会很快发生,也可能会在很长一段时间后发生。调度由Java实现决定,而不是Java spec
  • 指定
  • finalize 可能根本无法运行。例如,JVM可能会退出,同时选择立即清除所有对象,包括垃圾收集候选者,而根本不执行finalize方法。

一般来说,finalize方法几乎没有实际用途。通常的做法是定义并调用您自己的方法(teardownshutdown,无论您想要什么名称),以便在使用完对象后立即释放任何资源。

{9}及以后documented herediscussed here已正式弃用Object::finalize()方法。引用文档:

  

已弃用。最终确定机制本质上存在问题。最终确定可能导致性能问题,死锁和挂起。终结器中的错误可能导致资源泄漏;如果不再需要,则无法取消最终确定;并且在调用不同对象的方法之间没有指定排序。此外,无法保证最终确定的时间。只有在无限期延迟之后,才可以在可终结对象上调用finalize方法(如果有的话)。其实例包含非堆资源的类应该提供一种方法来启用这些资源的显式释放,并且它们还应该在适当时实现AutoCloseable。当对象无法访问时,Cleaner和PhantomReference提供了更灵活有效的方法来释放资源。

关于java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore