java中的Longs太苛刻了吗?为什么这样?

时间:2012-05-17 06:47:07

标签: java wrapper long-integer

我有一个Long变量说,

private Long m_prevPacketRecvdTime = null;

现在我有一个setter / getter对,

    public void setM_prevPacketRecvdTime() {
        if (this.m_prevPacketRecvdTime == null) {
            this.m_prevPacketRecvdTime = new Long(System.currentTimeMillis());
        } else {
            // Why to create a new Object every time
                    //Why I can't just set the new value
                    //Why use new operator here instead of an Assignment or set method call
        }
    }

而不是传统的setter方法,我想改进它,通过1.传递long而不是Long,2。只创建一个新Long,剩下的时间只是将新值设置为现有的Long对象。但令我难以置信的是Long中没有这样的方法。

每次我们想要更改其值时,我们是否真的需要创建一个新的Long对象?我们如何为现有的Long对象设置一个新的long值(与longvalue()相反)?

更多信息 在寻找答案时,我也遇到了AtomicLong,它有类似的功能,但我不确定这对我是否有用。因为他们清楚地说AtomicLong“不能用作Long的替代品。

2 个答案:

答案 0 :(得分:6)

你不能,这是故意的。不可变对象具有许多优点 - 线程安全性,易用性,安全性和可预测性等。有了其他原因,请参阅Effective Java第15项,但Java中的包装类都是不可变的。

也就是说,您应该使用Long.valueOf(long)(或自动装箱)而不是new Long,因为Long.valueOf知道要缓存常用值。

在Java中分配相对便宜。不要太担心它。如果您可以生成硬数来证明切换到您自己的自定义可变包装类型值得额外的代码复杂性,那么这样做,但传统的不可变包装器是完全可用的。

答案 1 :(得分:2)

如果表现是最重要的方面,你应该考虑:

private long m_prevPacketRecvdTime = 0;

public void setM_prevPacketRecvdTime() {
    if (this.m_prevPacketRecvdTime == 0) {
        this.m_prevPacketRecvdTime = System.currentTimeMillis();
    }
}

它不仅更快,而且更简单。请注意'特殊值'0表示'未设置'。对于时间字段,我认为没关系。

要考虑的另一个问题是使用System.currentTimeMillis()。这是一个相对较慢的操作,甚至可能比分配新对象更慢(使用new Long())。改善这一点有点棘手。一种选择可能是将当前时间保持在不同的线程中:

while (!stopped) {
    Thread.sleep(100);
    currentTime = System.currentTimeMillis();
}

然后每次只访问(静态)字段System.currentTimeMillis()而不是调用currentTime