Java中的`* this = rhs`?

时间:2011-02-21 16:39:39

标签: java c++

我来自C ++世界,我找不到以下的Java替代方案(如果有的话):

struct SomeStruct
{
    SomeStruct(){}
    SomeStruct(const SomeStruct& rhs)
    {
        *this = rhs;
    }
};

我需要这个的原因是我有一个现有对象的缓存,所以我不想创建另一个实例,只是为了“克隆”现有的实例,如下所示:

public class SomeObject
{
    private static Hashtable _objects;
    SomeObject()
    {
        SomeObject obj = _objects.get(some_key);
        if (obj != null) {
            // *this = obj;
            // instead of: 
            // this.something = obj.something;
            // this.something1 = obj.something1;
            // this.something2 = obj.something2;
            // a zillion fields....
        }
    }
};

编辑:

抱歉,我对某些事情感到困惑(仍然需要学习Java和C ++)。

谢谢

7 个答案:

答案 0 :(得分:7)

最接近的是Object.clone(),但请先阅读Effective Java的相关部分。

如果删除了一些要求,可能会有更简单的方法来执行您想要的操作。例如,如果使对象不可变,则不需要将数据复制到另一个对象中。相反,您可以返回对原始对象的引用。这比成员副本快得多,并且还有许多其他好处,例如更容易编写线程安全的代码。

答案 1 :(得分:7)

没有直接的等价物。 Object.clone()是最接近的,但它会创建一个新实例并执行浅层复制。你可以用反射写一些通用的东西。

答案 2 :(得分:3)

public class SomeObject
{
    private static Hashtable _objects;

    public static SomeObject getInstance(SomeKey some_key)
    {
        return _objects.get(some_key);
    }
}

答案 3 :(得分:2)

从您的问题中不清楚您是在尝试实现不可变对象的纯缓存,还是保留“模板”对象的缓存,并返回可由客户端进行变更的副本。我将假设后者。

假设您确实想要返回原件的副本。没有非常好的方法在Java中实现复制构造函数。 Clone稍微好一些,所以你应该隐藏静态工厂方法背后的构造函数:

public static SomeObject getInstance(...) {
  SomeObject cached = ...;
  if (cached != null) {
    return cached.clone();
  }
  ...
}

也许在您的特定情况下,您可以分离对象的不可变和有状态部分?如果是这样,对对象模型的一些更改可以使代码更清晰(也更有效)?

答案 4 :(得分:1)

在Java中,如果你想拥有一个与拷贝构造函数相对应的构造函数,你必须自己实现它。在某些情况下,这意味着您必须将字段从一个对象实例复制到另一个对象实例,而在其他情况下,这意味着您必须实现完整的深层复制 - 以递归方式遍历复制文件中参数的引用字段。

这取决于你想要什么 - 是否应该复制objects散列表?或者两个对象是否应该共享对它的引用?有关详细信息,请参阅this question

答案 5 :(得分:0)

我不知道在不使用的情况下将字段的所有内容从一个对象复制到另一个对象的任何通用方法;

  • 反射
  • 生成的代码。
  • 使用Unsafe类进行复制。

反射在运行时更容易使用,但效率不如生成的代码。 (但非常接近)我生成了我的数据模型,所以我使用了这个选项。

Unsafe类比反射更快,但不跨平台且不安全。它几乎与生成的代码一样快。 ;)

就速度而言,如果生成的代码是1x,则Unsafe为1.5 - 2x,对于高度缓存的数据,反射速度要慢2-4倍。对于缓存不佳的数据,您不会看到差异。

答案 6 :(得分:-1)

您应该使用Singleton模式。您可以创建SomeObject的静态实例并使用该实例。

   private static class SingletonHolder { 
     public static final SomeObject INSTANCE = new SomeObject();
   }

   public static SomeObject getInstance() {
     return SingletonHolder.INSTANCE;
   }

但是不要陷入Singleton陷阱,限制对getInstance()的调用!