晕, 你自己写一个不行么?public class Test { private int x; private int y; public Test(){} public Test(int x, int y) { this.x = x; this.y = y; }
public Test(Test test) { this.x = test.getX(); this.y = test.getY(); } public int getX() { return this.x; }
public int getY() { return this.y; } }
这就叫最大弊端,JAVA的弊端多着里
入门知识:Java不用拷贝,实参是无论如何也不会被形参改变的. ( ﹁ ﹁ )
答: 1)并不是所有的形参是引用时都需要一个拷贝. 2)默认时:JAVA是不拷贝的,这样可节省许多执行拷贝所化的时间,同时又节省了空间. 3)在自己确定需要拷贝的地方,自己调用一下clone()就行了.最简单的做法是:在自己的类中定义重写clone()方法( 效果类似于:相当于你在C++中定义了一个:拷贝构造器):(即:你总得要写点儿代码) class A implements Cloneable { ... public Object clone() { return super.clone(); } }
实参可以在这种情况下被形参改变的: public void method(A a) { a.setX(1); }public class A { private int x; public void setX(int x) { this.x = x } }不过一般来说,都不推荐这样去修改实参的,所以不需要拷贝.
{
private int x;
private int y; public Test(){} public Test(int x, int y)
{
this.x = x;
this.y = y;
}
public Test(Test test)
{
this.x = test.getX();
this.y = test.getY();
} public int getX()
{
return this.x;
}
public int getY()
{
return this.y;
}
}
1)并不是所有的形参是引用时都需要一个拷贝.
2)默认时:JAVA是不拷贝的,这样可节省许多执行拷贝所化的时间,同时又节省了空间.
3)在自己确定需要拷贝的地方,自己调用一下clone()就行了.最简单的做法是:在自己的类中定义重写clone()方法( 效果类似于:相当于你在C++中定义了一个:拷贝构造器):(即:你总得要写点儿代码)
class A implements Cloneable
{
...
public Object clone() {
return super.clone();
}
}
public void method(A a) {
a.setX(1);
}public class A {
private int x;
public void setX(int x) {
this.x = x
}
}不过一般来说,都不推荐这样去修改实参的,所以不需要拷贝.
我觉得你没有理解java的参数的传递的含义,
传递引用参数的时候根本就没有所谓的拷贝,并没有新的对象产生,拷贝的也是引用值本身(相当于地址值),这不很好吗?
特别是clone方法是protected,那基本上就是等于没有这东西,因为经常不同包来进行深度复制。
为什么说clone方法是protect而不是public原因是什么?因为所有的类都来自object,java是为了保证
A类只能克隆A对象,B类只能克隆B对象,并且object类的clone方法已经为我们做了很多,只要你的域的对象是
基本类型的和不可变类型的,就只需super.clone()即可。
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;class UserBufferImage extends BufferedImage implements Cloneable
{
BufferedImage temp;
public UserBufferImage(int width, int height, int imageType)
{
super(width, height, imageType);
// TODO Auto-generated constructor stub
}
public void setImage(String a)
{
try
{
temp = ImageIO.read(new File("apple.jpg"));
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public BufferedImage getImage1()
{
return temp;
}
public Object clone() {
UserBufferImage o = null;
try {
o = (UserBufferImage) super.clone();
o.temp = (BufferedImage) temp.clone();
} catch(CloneNotSupportedException e){
e.printStackTrace();
}
return o;
}
public static void getImage()
{
}
}
class temp
{
public static void main(String[] args)
{
UserBufferImage x = new UserBufferImage(20, 20, 3); UserBufferImage y = (UserBufferImage) x.clone();
System.out.println(x.hashCode());
System.out.println(y.hashCode());
}
}
错误原因:BufferedImage类是不能clone的.它没有实现Clonable接口.
其实你的UserBufferImage类只要实现浅复制就行了:
即:public Object clone() {
return super.clone();
}
复制好后,新对象随时可以通过setImage(String a)指向新图像.
输出的hashCode不同
调用了object的hashCode方法,她返回的是当前对象的地址值。
你的hashCode()不同不正好证明了,你已经实现了拷贝吗,二者X,y指向两个不同的对象(内容一样),
其实我想表达的本意是
假如有xxx.method(trueA);这样的调用
那么trueA作为实参,它指向的地址是不会被method方法里的形参改变的.不过楼主说的情况,避免实参与形参所指向的实例被改变,确实需要clone,在8楼闪了舌头,抱歉抱歉.
楼上几位前辈的知识学习了ψ(._. )>
面壁思过去~>_<~
既然楼主必须要"深度复制"图像,我就提供我的设计方法(我已测试是成功的),请楼主再测试测试.
参考代码如下://具有深复制的BufferImage
class UserBufferImage extends BufferedImage implements Cloneable
{
BufferedImage temp;
public UserBufferImage(int width, int height, int imageType)
{
super(width, height, imageType);
// TODO Auto-generated constructor stub
}
public void setImage(String a)
{
try
{
temp = ImageIO.read(new File("apple.jpg"));
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public BufferedImage getImage1()
{
return temp;
}
public Object clone() {
UserBufferImage o = null;
try {
o = (UserBufferImage) super.clone();
o.temp = myclone();
} catch (CloneNotSupportedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
//从temp复制一个新的BufferedImage对象
private BufferedImage myclone()
{
BufferedImage o=null;
o = new BufferedImage(temp.getWidth(null),temp.getHeight(null),BufferedImage.TYPE_INT_RGB);
Graphics g = o.getGraphics();
g.drawImage(temp,0,0,null);
g.dispose();
return o;
}
public static void getImage()
{
}
}