class ArrayTest
{
public static void main(String[] args)
{
Point[] pt1=new Point[]{new Point(1,1),new Point(3,3),new Point(2,2)};
Point[] pt2=(Point[])pt1.clone();
System.out.println(pt1==pt2); //输出false了,好像不是引用了同一个堆内存
pt2[1].x=5;
pt2[1].y=5;
System.out.println(pt1[1].x+","+pt1[1].y); //pt1的xy坐标受到了影响,不知何解?
}
}
class Point implements Cloneable
{
int x,y;
Point(int x,int y)
{
this.x=x;
this.y=y;
}
public Object clone()
{
Object o=null;
try
{
o=super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(e.toString());
}
return o;
}
}
12 个解决方案
#1
你的那个Point 的clone方法根本不会执行。
#2
Point[] pt2=(Point[])pt1.clone();,clone()调用的是数据对象pt1的方法,而不是类Point创建的clone方法.
#3
Point[] pt2=(Point[])pt1.clone();,clone()调用的是数据对象pt1的方法,而不是类Point创建的clone方法.
#4
Point[] pt2=(Point[])pt1.clone();,clone()调用的是数据对象pt1的方法,而不是类Point创建的clone方法.
#5
为什么不被执行啊?应该怎么改呢?
#6
数组[] 你只能自己控制复制,也就是调用里面每个对象的clone方法!
#7
规则
1,Object 的clone()方法是protected,所以不能从外部直接调用。
要么override,要么在override的方法内部调用。
2, 调用Object类的clone方法时,如果子类没有实现cloneable接口
那么会抛出CloneNotSupportedException异常。
3,Object的clone方法是浅拷贝,也就是说对于参照类型的域只拷贝
指针。如果要实现深拷贝,那么需要覆盖clone类,手动拷贝参照类型。
class TestClone implements Cloneable
{
private int data;
public void setData( int i )
{
data = i;
}
public int getData()
{
return data;
}
protected Object clone() throws CloneNotSupportedException
{
TestCloneTarget newData = new TestCloneTarget();
newData.data = this.data;
return newData;
}
}
我以前做过一个试验给你改一下
1,Object 的clone()方法是protected,所以不能从外部直接调用。
要么override,要么在override的方法内部调用。
2, 调用Object类的clone方法时,如果子类没有实现cloneable接口
那么会抛出CloneNotSupportedException异常。
3,Object的clone方法是浅拷贝,也就是说对于参照类型的域只拷贝
指针。如果要实现深拷贝,那么需要覆盖clone类,手动拷贝参照类型。
class TestClone implements Cloneable
{
private int data;
public void setData( int i )
{
data = i;
}
public int getData()
{
return data;
}
protected Object clone() throws CloneNotSupportedException
{
TestCloneTarget newData = new TestCloneTarget();
newData.data = this.data;
return newData;
}
}
我以前做过一个试验给你改一下
#8
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
Sample sample = new Sample();
//sample.testClone();
Point[] pt1=new Point[]{new Point(1,1),new Point(3,3),new Point(2,2)};
Point[] pt2=(Point[])pt1.clone();
System.out.println(pt1==pt2);
pt2[1].x=5;
pt2[1].y=5;
System.out.println(pt1[1].x+","+pt1[1].y);
System.out.println(pt1[1].hashCode());
System.out.println(pt2[1].hashCode());
System.out.println();
pt1[1].x=3;
pt1[1].y=3;
Point[] pt3= new Point[pt1.length];
System.arraycopy(pt1,0,pt3,0,pt1.length);
System.out.println(pt1==pt3);
pt3[1].x=5;
pt3[1].y=5;
System.out.println(pt1[1].x+","+pt1[1].y);
System.out.println(pt1[1].hashCode());
System.out.println(pt3[1].hashCode());
System.out.println();
try {
pt1[1].x=3;
pt1[1].y=3;
Point[] pt4= new Point[pt1.length];
for (int i=0; i<pt4.length; i++) {
pt4[i] = (Point)pt1[i].clone();
}
System.out.println(pt1==pt4);
pt4[1].x=5;
pt4[1].y=5;
System.out.println(pt1[1].x+","+pt1[1].y);
System.out.println(pt1[1].hashCode());
System.out.println(pt4[1].hashCode());
} catch (Exception e) {
}
System.out.println();
int [] numbers = { 2, 3, 4, 5};
int [] numbersClone = (int[])numbers.clone();
numbersClone[2] = 0;
System.out.println("Clone numbers:"+numbers[2]);
System.out.println("Clone numbers:"+numbersClone[2]);
numbers[2] = 4;
int [] numbersCopy = new int[numbers.length];
System.arraycopy(numbers, 0, numbersCopy, 0, numbersCopy.length);
numbersCopy[2] = 0;
System.out.println("Copy numbers:"+numbers[2]);
System.out.println("Copy numbers:"+numbersCopy[2]);
}
#9
做实验可以看到,数组的拷贝和复制对于基本类型来说是不同的。
比如
|-----------|
ar1-> | 10 | 20 30|
|-----------|
如果做附值、ar2=ar1那么就是
|-----------|
ar1-> | 10 | 20 30| <-ar2
|-----------|
如果对ar1做拷贝或复制那么结果就是
(ar2=ar1.clone)
|-----------|
ar1-> | 10 | 20 30|
|-----------|
|-----------|
ar2-> | 10 | 20 30|
|-----------|
但是如果是指针那么效果就一样了
想象一下 10,20,30 都是地址,那么无论怎么拷贝都是地址。
也就是说它们指向的对象永远都是同一个
比如
|-----------|
ar1-> | 10 | 20 30|
|-----------|
如果做附值、ar2=ar1那么就是
|-----------|
ar1-> | 10 | 20 30| <-ar2
|-----------|
如果对ar1做拷贝或复制那么结果就是
(ar2=ar1.clone)
|-----------|
ar1-> | 10 | 20 30|
|-----------|
|-----------|
ar2-> | 10 | 20 30|
|-----------|
但是如果是指针那么效果就一样了
想象一下 10,20,30 都是地址,那么无论怎么拷贝都是地址。
也就是说它们指向的对象永远都是同一个
#10
晕 格式乱了
#11
楼上的有点复杂了,我自己想了一下,这么解决不知对不对
class ArrayTest
{
public static void main(String[] args)
{
Point[] pt1=new Point[]{new Point(1,1),new Point(3,3),new Point(2,2)};
Point[] pt2=new Point[pt1.length];
for(int i=0;i<pt2.length;i++)
{
for(int j=0;j<pt1.length;j++)
{
pt2[i]=(Point)pt1[i].clone();
}
}
//对数数组 pt2 的改变不会影响对象数组 pt1
pt2[1].x=5;
pt2[1].y=5;
System.out.println("数组 pt2 的值:");
for(int i=0;i<pt2.length;i++)
{
System.out.println(pt2[i].x+","+pt2[i].y);
}
System.out.println("\n数组 pt1 的值:");
for(int i=0;i<pt1.length;i++)
{
System.out.println(pt1[i].x+","+pt1[i].y);
}
}
}
class Point implements Cloneable
{
int x,y;
Point(int x,int y)
{
this.x=x;
this.y=y;
}
public Object clone()
{
Object o=null;
try
{
o=super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(e.toString());
}
return o;
}
}
#12
刚才的代码贴错了,我的解决方法是这样的,不知是否正确
class ArrayTest
{
public static void main(String[] args)
{
Point[] pt1=new Point[]{new Point(1,1),new Point(3,3),new Point(2,2)};
Point[] pt2=new Point[pt1.length];
for(int i=0;i<pt2.length;i++)
{
pt2[i]=(Point)pt1[i].clone();
}
//对数数组 pt2 的改变不会影响对象数组 pt1
pt2[1].x=5;
pt2[1].y=5;
System.out.println("数组 pt2 的值:");
for(int i=0;i<pt2.length;i++)
{
System.out.println(pt2[i].x+","+pt2[i].y);
}
System.out.println("\n数组 pt1 的值:");
for(int i=0;i<pt1.length;i++)
{
System.out.println(pt1[i].x+","+pt1[i].y);
}
}
}
class Point implements Cloneable
{
int x,y;
Point(int x,int y)
{
this.x=x;
this.y=y;
}
public Object clone()
{
Object o=null;
try
{
o=super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(e.toString());
}
return o;
}
}
#1
你的那个Point 的clone方法根本不会执行。
#2
Point[] pt2=(Point[])pt1.clone();,clone()调用的是数据对象pt1的方法,而不是类Point创建的clone方法.
#3
Point[] pt2=(Point[])pt1.clone();,clone()调用的是数据对象pt1的方法,而不是类Point创建的clone方法.
#4
Point[] pt2=(Point[])pt1.clone();,clone()调用的是数据对象pt1的方法,而不是类Point创建的clone方法.
#5
为什么不被执行啊?应该怎么改呢?
#6
数组[] 你只能自己控制复制,也就是调用里面每个对象的clone方法!
#7
规则
1,Object 的clone()方法是protected,所以不能从外部直接调用。
要么override,要么在override的方法内部调用。
2, 调用Object类的clone方法时,如果子类没有实现cloneable接口
那么会抛出CloneNotSupportedException异常。
3,Object的clone方法是浅拷贝,也就是说对于参照类型的域只拷贝
指针。如果要实现深拷贝,那么需要覆盖clone类,手动拷贝参照类型。
class TestClone implements Cloneable
{
private int data;
public void setData( int i )
{
data = i;
}
public int getData()
{
return data;
}
protected Object clone() throws CloneNotSupportedException
{
TestCloneTarget newData = new TestCloneTarget();
newData.data = this.data;
return newData;
}
}
我以前做过一个试验给你改一下
1,Object 的clone()方法是protected,所以不能从外部直接调用。
要么override,要么在override的方法内部调用。
2, 调用Object类的clone方法时,如果子类没有实现cloneable接口
那么会抛出CloneNotSupportedException异常。
3,Object的clone方法是浅拷贝,也就是说对于参照类型的域只拷贝
指针。如果要实现深拷贝,那么需要覆盖clone类,手动拷贝参照类型。
class TestClone implements Cloneable
{
private int data;
public void setData( int i )
{
data = i;
}
public int getData()
{
return data;
}
protected Object clone() throws CloneNotSupportedException
{
TestCloneTarget newData = new TestCloneTarget();
newData.data = this.data;
return newData;
}
}
我以前做过一个试验给你改一下
#8
public static void main(String[] args) {
// TODO 自動生成されたメソッド・スタブ
Sample sample = new Sample();
//sample.testClone();
Point[] pt1=new Point[]{new Point(1,1),new Point(3,3),new Point(2,2)};
Point[] pt2=(Point[])pt1.clone();
System.out.println(pt1==pt2);
pt2[1].x=5;
pt2[1].y=5;
System.out.println(pt1[1].x+","+pt1[1].y);
System.out.println(pt1[1].hashCode());
System.out.println(pt2[1].hashCode());
System.out.println();
pt1[1].x=3;
pt1[1].y=3;
Point[] pt3= new Point[pt1.length];
System.arraycopy(pt1,0,pt3,0,pt1.length);
System.out.println(pt1==pt3);
pt3[1].x=5;
pt3[1].y=5;
System.out.println(pt1[1].x+","+pt1[1].y);
System.out.println(pt1[1].hashCode());
System.out.println(pt3[1].hashCode());
System.out.println();
try {
pt1[1].x=3;
pt1[1].y=3;
Point[] pt4= new Point[pt1.length];
for (int i=0; i<pt4.length; i++) {
pt4[i] = (Point)pt1[i].clone();
}
System.out.println(pt1==pt4);
pt4[1].x=5;
pt4[1].y=5;
System.out.println(pt1[1].x+","+pt1[1].y);
System.out.println(pt1[1].hashCode());
System.out.println(pt4[1].hashCode());
} catch (Exception e) {
}
System.out.println();
int [] numbers = { 2, 3, 4, 5};
int [] numbersClone = (int[])numbers.clone();
numbersClone[2] = 0;
System.out.println("Clone numbers:"+numbers[2]);
System.out.println("Clone numbers:"+numbersClone[2]);
numbers[2] = 4;
int [] numbersCopy = new int[numbers.length];
System.arraycopy(numbers, 0, numbersCopy, 0, numbersCopy.length);
numbersCopy[2] = 0;
System.out.println("Copy numbers:"+numbers[2]);
System.out.println("Copy numbers:"+numbersCopy[2]);
}
#9
做实验可以看到,数组的拷贝和复制对于基本类型来说是不同的。
比如
|-----------|
ar1-> | 10 | 20 30|
|-----------|
如果做附值、ar2=ar1那么就是
|-----------|
ar1-> | 10 | 20 30| <-ar2
|-----------|
如果对ar1做拷贝或复制那么结果就是
(ar2=ar1.clone)
|-----------|
ar1-> | 10 | 20 30|
|-----------|
|-----------|
ar2-> | 10 | 20 30|
|-----------|
但是如果是指针那么效果就一样了
想象一下 10,20,30 都是地址,那么无论怎么拷贝都是地址。
也就是说它们指向的对象永远都是同一个
比如
|-----------|
ar1-> | 10 | 20 30|
|-----------|
如果做附值、ar2=ar1那么就是
|-----------|
ar1-> | 10 | 20 30| <-ar2
|-----------|
如果对ar1做拷贝或复制那么结果就是
(ar2=ar1.clone)
|-----------|
ar1-> | 10 | 20 30|
|-----------|
|-----------|
ar2-> | 10 | 20 30|
|-----------|
但是如果是指针那么效果就一样了
想象一下 10,20,30 都是地址,那么无论怎么拷贝都是地址。
也就是说它们指向的对象永远都是同一个
#10
晕 格式乱了
#11
楼上的有点复杂了,我自己想了一下,这么解决不知对不对
class ArrayTest
{
public static void main(String[] args)
{
Point[] pt1=new Point[]{new Point(1,1),new Point(3,3),new Point(2,2)};
Point[] pt2=new Point[pt1.length];
for(int i=0;i<pt2.length;i++)
{
for(int j=0;j<pt1.length;j++)
{
pt2[i]=(Point)pt1[i].clone();
}
}
//对数数组 pt2 的改变不会影响对象数组 pt1
pt2[1].x=5;
pt2[1].y=5;
System.out.println("数组 pt2 的值:");
for(int i=0;i<pt2.length;i++)
{
System.out.println(pt2[i].x+","+pt2[i].y);
}
System.out.println("\n数组 pt1 的值:");
for(int i=0;i<pt1.length;i++)
{
System.out.println(pt1[i].x+","+pt1[i].y);
}
}
}
class Point implements Cloneable
{
int x,y;
Point(int x,int y)
{
this.x=x;
this.y=y;
}
public Object clone()
{
Object o=null;
try
{
o=super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(e.toString());
}
return o;
}
}
#12
刚才的代码贴错了,我的解决方法是这样的,不知是否正确
class ArrayTest
{
public static void main(String[] args)
{
Point[] pt1=new Point[]{new Point(1,1),new Point(3,3),new Point(2,2)};
Point[] pt2=new Point[pt1.length];
for(int i=0;i<pt2.length;i++)
{
pt2[i]=(Point)pt1[i].clone();
}
//对数数组 pt2 的改变不会影响对象数组 pt1
pt2[1].x=5;
pt2[1].y=5;
System.out.println("数组 pt2 的值:");
for(int i=0;i<pt2.length;i++)
{
System.out.println(pt2[i].x+","+pt2[i].y);
}
System.out.println("\n数组 pt1 的值:");
for(int i=0;i<pt1.length;i++)
{
System.out.println(pt1[i].x+","+pt1[i].y);
}
}
}
class Point implements Cloneable
{
int x,y;
Point(int x,int y)
{
this.x=x;
this.y=y;
}
public Object clone()
{
Object o=null;
try
{
o=super.clone();
}
catch(CloneNotSupportedException e)
{
System.out.println(e.toString());
}
return o;
}
}