相关疑难解决方法(0)

Java:Cloneable接口的基本原理

为什么界面中没有.clone()指定方法java.lang.Cloneable

java specifications clone cloneable

32
推荐指数
4
解决办法
7508
查看次数

为什么clone()是复制数组的最佳方法?

这对我来说是一种耻辱,但我不知道:

您应该使用clone来复制数组,因为这通常是最快的方法.

正如Josh Bloch在本博客中所述:http://www.artima.com/intv/bloch13.html

我总是用System.arraycopy(...).这两种方法都是原生的,所以可能没有深入到我无法弄清楚的库的来源,为什么会如此.

我的问题很简单:为什么它是最快的方式? 有什么区别System.arraycopy这里 解释不同之处,但它没有回答为什么Josh Bloch认为clone()最快的方式.

java arrays clone copy

28
推荐指数
3
解决办法
3675
查看次数

为什么#clone()不在Cloneable接口中?

我正在阅读正确执行数组的深层副本,但是我对如何#clone()实现它感到困惑.它是java.lang.Object该类的成员,但如果您阅读了javadoc:

首先,如果此对象的类未实现Cloneable接口,则抛出CloneNotSupportedException.

那么为什么要首先定义clone那里的方法呢?当然,如果方法只能在存在接口时使用,则将该方法放在接口中.该Cloneable接口本身是空的; 它只是Java使用的标记接口,以确保使用该clone方法是合法的.

这样做也会消除使用泛型来确保类型安全的能力:

class Foo implements Cloneable { // Valid.
    @Override
    public Object clone() throws CloneNotSupportedException {
        // ...
    }
}

class TypeSafeFoo implements Cloneable<TypeSafeFoo> { // Not valid.
    @Override
    public TypeSafeFoo clone() throws CloneNotSupportedException {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

为什么Java以这种方式完成它?我确信他们有合理的理由,但我似乎无法弄明白.

java

14
推荐指数
2
解决办法
3761
查看次数

为什么Java 8中的Cloneable中没有默认的clone()

Cloneable在Java中本质上是破碎的.具体来说,我对界面的最大问题是它需要一种不定义方法本身的方法行为.因此,如果遍历Cloneable列表,则必须使用反射来访问其定义的行为.但是,在Java 8中,我们现在有默认方法,现在我问为什么没有默认clone()方法Cloneable.

我理解为什么接口不能默认Object方法,但是,这是一个明确的设计决策,因此可以做出异常.

我有点想到弃用Object.clone()并将其内部代码更改为:

if(this instanceof Cloneable) {
    return ((Cloneable) this).clone();
}
else {
    throw new CloneNotSupportedException();
}
Run Code Online (Sandbox Code Playgroud)

并继续前进任何魔法使其clone()成为默认方法Cloneable.这并没有真正解决,clone()仍然可以很容易地错误地实现,但这本身就是另一个讨论.

据我所知,这种变化将完全向后兼容:

  1. 当前覆盖clone()但未实现的类Cloneable(为什么?!)在技术上仍然可以(即使在功能上不可能,但这与以前没有什么不同).
  2. 当前覆盖clone()但实现的类Cloneable在其实现上仍将起相同的作用.
  3. 当前没有覆盖clone(),但确实实现Cloneable(为什么?!)的类现在将遵循规范,即使它在功能上并不完全正确.
  4. 使用反射并提到的那些Object.clone()仍然可以在功能上工作.
  5. super.clone()即使它正在引用,它在功能上仍然是相同的Object.clone().

更不用说这将解决一个巨大的问题Cloneable.虽然繁琐且仍然容易错误地实现,但它将解决界面的巨大面向对象问题.

我能看到的唯一问题是那些实现Cloneable没有义务覆盖的问题clone(),但这与以前没有什么不同.

这已在内部进行过讨论,但从未取得成果吗?如果是这样,为什么?如果是因为接口不能默认使用Object方法,那么在这种情况下做出异常是否有意义,因为所有继承Cloneable的对象都是期待clone()的?

java clone cloneable java-8 default-method

11
推荐指数
2
解决办法
7372
查看次数

为什么Cloneable没有clone()?

我试图了解 Object.clone() 在 Java 中是如何工作的。我发现了以下事实:

  • 类实现该Cloneable接口以向 Object.clone() 方法指示该方法对该类的实例进行逐字段复制是合法的。
  • 在未实现该接口的实例上调用 的Object方法会导致抛出异常。cloneCloneableCloneNotSupportedException
  • 但请注意,该Cloneable接口不包含该clone方法。因此,实现Cloneable不负责因未实现而引发任何错误/异常clone()
  • 相反,Object.clone()是一个本机方法,它从此cpp方法中调用 并抛出。JVM_Clone jvm.cppCloneNotSupportedException

疑点:

Q1. 为什么Java设计者会做出这样的设计选择并这样实现呢?为什么不在其自身clone()中进行定义Cloneable,如果实现类没有提供clone().

Q2。Cloneable为什么要在运行时检查实例是否实现?

Q3。有什么具体原因要在本机代码中检查它吗?

Q4。奇怪的是Object它本身并没有实现Cloneable,但提供了一个实现clone(),它反过来检查是否有任何类实现了Cloneable实现clone()。理想情况下,不应该Object实现Cloneable(声明clone())然后提供实现吗clone()

PS:我知道在一个问题中提出多个问题是一个坏主意。但这些都是密切相关的问题。我很可能会问一个问题,比如“为什么不Cloneable包含clone()?” 但是,我觉得,为了更好地回答这个疑问,必须涵盖这一设计决策的各个微妙方面。我努力思考更多,并提出了可能的不同微妙方面,并逐点明确地询问它们,以便回答者不会错过它们并给出总体完整的答案。

java

5
推荐指数
1
解决办法
1394
查看次数

为什么CopyOnWriteArraySet不实现Cloneable接口,而CopyOnWriteArrayList呢?

在这个错误报告中,Doug Lea写道(指的是JDK 5.0的预发布版本):

虽然CopyOnWriteArraySet声明Cloneable,它没有界定公共clone方法.

但它最终会CopyOnWriteArraySet完全没有实现Cloneable接口!(在Java SE 6,7和8中都是如此)

如何CopyOnWriteArraySet从不同的CopyOnWriteArrayList关于克隆?有没有人想要克隆它?

PS我明白clone()不推荐这CopyOnWriteArraySet是基于CopyOnWriteArrayList内部的.

java collections clone cloneable

1
推荐指数
1
解决办法
155
查看次数