特别是形参是引用时,需要一个拷贝,避免对实参值的改变。可是C++提供拷贝构造,而JAVA没有,这十分讨厌。
特别是clone方法是protected,那基本上就是等于没有这东西,因为经常不同包来进行深度复制。

解决方案 »

  1.   

    clone 方法是由类的提供者重写的
      

  2.   

    每个类都有不同的 clone 实现呀。
      

  3.   

    自己使用clone方法的时候定义为public的
      

  4.   

    晕, 你自己写一个不行么?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;
        }
    }
      

  5.   

    这就叫最大弊端,JAVA的弊端多着里
      

  6.   

    入门知识:Java不用拷贝,实参是无论如何也不会被形参改变的. ( ﹁ ﹁ ) 
      

  7.   

    答:
    1)并不是所有的形参是引用时都需要一个拷贝.
    2)默认时:JAVA是不拷贝的,这样可节省许多执行拷贝所化的时间,同时又节省了空间.
    3)在自己确定需要拷贝的地方,自己调用一下clone()就行了.最简单的做法是:在自己的类中定义重写clone()方法( 效果类似于:相当于你在C++中定义了一个:拷贝构造器):(即:你总得要写点儿代码)
    class A implements Cloneable
    {
    ...
    public Object clone() { 
      return super.clone(); 

    }
      

  8.   

    实参可以在这种情况下被形参改变的:
    public void method(A a) {
        a.setX(1);
    }public class A {
        private int x;
        public void setX(int x) {
            this.x = x
        }
    }不过一般来说,都不推荐这样去修改实参的,所以不需要拷贝.
      

  9.   

    特别是形参是引用时,需要一个拷贝,避免对实参值的改变?
    我觉得你没有理解java的参数的传递的含义,
    传递引用参数的时候根本就没有所谓的拷贝,并没有新的对象产生,拷贝的也是引用值本身(相当于地址值),这不很好吗?
    特别是clone方法是protected,那基本上就是等于没有这东西,因为经常不同包来进行深度复制。
    为什么说clone方法是protect而不是public原因是什么?因为所有的类都来自object,java是为了保证
    A类只能克隆A对象,B类只能克隆B对象,并且object类的clone方法已经为我们做了很多,只要你的域的对象是
    基本类型的和不可变类型的,就只需super.clone()即可。
      

  10.   

    如果大家讲得有道理,那看下这个程序,为什么不能实现复制。import java.awt.image.BufferedImage;
    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());
    }
    }
      

  11.   

    答:
    错误原因:BufferedImage类是不能clone的.它没有实现Clonable接口.
    其实你的UserBufferImage类只要实现浅复制就行了:
    即:public Object clone() {
     return super.clone();
    }
    复制好后,新对象随时可以通过setImage(String a)指向新图像.
      

  12.   

    去掉 o.temp = (BufferedImage) temp.clone();这句因为该类并没有实现该接口
    输出的hashCode不同
    调用了object的hashCode方法,她返回的是当前对象的地址值。
    你的hashCode()不同不正好证明了,你已经实现了拷贝吗,二者X,y指向两个不同的对象(内容一样),
      

  13.   

    呃,的确啊.
    其实我想表达的本意是
    假如有xxx.method(trueA);这样的调用
    那么trueA作为实参,它指向的地址是不会被method方法里的形参改变的.不过楼主说的情况,避免实参与形参所指向的实例被改变,确实需要clone,在8楼闪了舌头,抱歉抱歉.
    楼上几位前辈的知识学习了ψ(._. )> 
    面壁思过去~>_<~
      

  14.   

    传参时加final 就不会改变了吧
      

  15.   

    答:
    既然楼主必须要"深度复制"图像,我就提供我的设计方法(我已测试是成功的),请楼主再测试测试.
    参考代码如下://具有深复制的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()
        {
            
        }
        
    }
      

  16.   

    其实拷贝函数感觉不是java的弊端 而是 c++的缺陷 容易造成析构不清。