Create Clone.java from the following source and compile.
note that interface D picks up clone() two times; once
from B extends A implements Cloneable B and once
from C extends A implements Cloneable
Compiling yields:
D:\Java\Cloneable>javac -classpath .;d:\java\jdk\1.1.2\lib\classes.zip
Clone.java
Clone.java:79: Reference to clone is ambiguous. It is defined in
java.lang.Object
clone() and java.lang.Object clone().
D d1 = (D) d0.clone();
^
1 error
i.e. we can't invoke the clone() method on a variable whose type
is D; i.e. an interface which picks up Cloneable through multiple
interface inheritance paths.
This is a very serious problem for us. Most of our development is
based on designs centered around passing interfaces, which is
prefereable in many cases. Some classes have such "diamond"
interface inheritance structure (i.e. we have an
OrderedCollectionInterface and a DictionaryInterface which both
extend from a basic CollectionInterface. The CollectionInterface
is defined to implement Cloneable and also defines a public Object
clone() method. Then, we've defined an AssociationList class which
implements OrderedCollectionInterface and DictionaryInterface, and
we get compile errors because of this false clone() ambiguity.
Workarounds: None. It is impossible to factor out Cloneable from
our interfaces; we can't push it higher because we use interfaces
as mixins so much that it will always happen. We want to keep
using interfaces and not have to bind more tightly to specific
implementation classes.
interface A extends Cloneable
{
public Object clone() throws CloneNotSupportedException;
}
interface B extends A
{ }
interface C extends A
{ }
interface D extends B, C
{ }
public class Clone implements D
{
private int i;
public Clone(int i)
{
this.i = i;
}
public Object clone()
{
Clone theClone = null;
try
{
theClone = (Clone) super.clone();
theClone.i = i;
}
catch (CloneNotSupportedException cnse)
{ }
return theClone;
}
public static void main(String argv[])
{
try
{
A a0 = new Clone(0);
A a1 = (A) a0.clone();
B b0 = new Clone(0);
B b1 = (B) b0.clone();
C c0 = new Clone(0);
C c1 = (C) c0.clone();
D d0 = new Clone(0);
D d1 = (D) d0.clone();
}
catch (CloneNotSupportedException cnse)
{ }
}
}
note that interface D picks up clone() two times; once
from B extends A implements Cloneable B and once
from C extends A implements Cloneable
Compiling yields:
D:\Java\Cloneable>javac -classpath .;d:\java\jdk\1.1.2\lib\classes.zip
Clone.java
Clone.java:79: Reference to clone is ambiguous. It is defined in
java.lang.Object
clone() and java.lang.Object clone().
D d1 = (D) d0.clone();
^
1 error
i.e. we can't invoke the clone() method on a variable whose type
is D; i.e. an interface which picks up Cloneable through multiple
interface inheritance paths.
This is a very serious problem for us. Most of our development is
based on designs centered around passing interfaces, which is
prefereable in many cases. Some classes have such "diamond"
interface inheritance structure (i.e. we have an
OrderedCollectionInterface and a DictionaryInterface which both
extend from a basic CollectionInterface. The CollectionInterface
is defined to implement Cloneable and also defines a public Object
clone() method. Then, we've defined an AssociationList class which
implements OrderedCollectionInterface and DictionaryInterface, and
we get compile errors because of this false clone() ambiguity.
Workarounds: None. It is impossible to factor out Cloneable from
our interfaces; we can't push it higher because we use interfaces
as mixins so much that it will always happen. We want to keep
using interfaces and not have to bind more tightly to specific
implementation classes.
interface A extends Cloneable
{
public Object clone() throws CloneNotSupportedException;
}
interface B extends A
{ }
interface C extends A
{ }
interface D extends B, C
{ }
public class Clone implements D
{
private int i;
public Clone(int i)
{
this.i = i;
}
public Object clone()
{
Clone theClone = null;
try
{
theClone = (Clone) super.clone();
theClone.i = i;
}
catch (CloneNotSupportedException cnse)
{ }
return theClone;
}
public static void main(String argv[])
{
try
{
A a0 = new Clone(0);
A a1 = (A) a0.clone();
B b0 = new Clone(0);
B b1 = (B) b0.clone();
C c0 = new Clone(0);
C c1 = (C) c0.clone();
D d0 = new Clone(0);
D d1 = (D) d0.clone();
}
catch (CloneNotSupportedException cnse)
{ }
}
}
- duplicates
-
JDK-1233993 Strange error message in the compiler
-
- Closed
-