0

I have written a class A such as following

class A <E> {  // class A has objects of E

    int x;

    private B<T> next // a object of inner class

    class B<T> { 
        // an inner class having objects of type T

        T[] elements = (T[]) Object[x];
        // has other stuff including many objects  
    }

 public A<E> func ( B<E> val ){
  Here I want to clone the value of val so that I can do different operations on other   
 }

The problem comes that I wish to write B<E> Temp = B<E>Value.clone() where Value is defined in the code.

but it says that clone is not visible.

What should I do to make it so....

Thanks a lot...

  • Can you provide a code sample which includes your `clone()` routine? You might also want to implement the `Cloneable` interface. – Johan Sjöberg Feb 16 '11 at 17:51

3 Answers3

1

clone() is protected so you just need to redefine in B to do whatever you need.

Peter Hull
  • 6,683
  • 4
  • 39
  • 48
  • What do you mean by redefine ??? Could you give an example ?? as in I need to implement Cloneable in the nested class or what ?? –  Feb 16 '11 at 18:00
  • 1
    Just overwrite it and increase its visibility: make it public. Inside, you will call super.clone() and then -- if needed -- you'll make a deep copy. – Costi Ciudatu Feb 16 '11 at 18:31
  • again could you give an example ... I wrote super.clone() in the inner class and eclipse does'nt let me run this. Thanks a lot... –  Feb 16 '11 at 18:35
0

It's better to not use clone() but to implement a copy constructor on B:

 class B extends A { 
    // an inner class having objects of type 
    List<String> strings = ArrayList<String>();

    public B(B that) {
       super(that); // call the superclass's copy constructor
       this.strings = new ArrayList<String>();
       this.strings.add(that.strings);
    }

    // ...
}

then call

public C func ( B val ){
   B clone = new B(val);
}

(removed the generics stuff to limit demonstration on the copy constructor itself)

Andreas Dolk
  • 113,398
  • 19
  • 180
  • 268
  • clone is broken, there are a lot of questions and answers on this topic (Example: http://stackoverflow.com/questions/2427883/clone-vs-copy-constructor-which-is-recommended-in-java) – Andreas Dolk Feb 16 '11 at 19:33
  • On "It's better to not use clone()", what if you're cloning a `B` type but are not sure of its runtime type (because it could be a subclass of `B`)? – Steve Kuo Feb 17 '11 at 07:01
  • @Steve Kuo - I don't understand that comment. A `B` is a `B` at runtime, a subclass of `B` is not a `B`. Subclassing was not part of the question, but anyway, I edited the question. Copy Constructor is compatible with inheritance. (and `clone` is still broken and we should simply avoid it). – Andreas Dolk Feb 17 '11 at 08:10
  • How is a subclass of `B` not a `B` (it will pass instanceof)? Are you saying `LinkedHashMap` is not a `HashMap`? – Steve Kuo Feb 17 '11 at 21:19
  • @Steve - A `LinkedHashMap` is a `LinkedHashMap` and it extends `HashMap`. You *create* it by calling the `LinkedHashMap` constructor. Calling `getClass()` on an instance of `LinkedHashMap` returns `"java.util.LinkedHashMap"`. *is-a* is ambigious in this case, I was not talking about inheritance, I was talking about the type of an instance. – Andreas Dolk Feb 18 '11 at 07:00
  • @Andreas_D: Your copy constructor answer is incomplete and incorrect if B can have subclasses - which it can, as its non-final. `public C func ( B val ){ B clone = new B(val); }` This code will always create a B instance, even if the val passed is actually a subclass of B. This is where clone is needed, but I agree it's tricky to use and somewhat broken in places. – davidfrancis May 06 '11 at 11:06
  • @Zebsy - subclasses is a different story - if you want to clone some `E extends B`, then call the copy constructor of `E`. If you use `new B(B source)` with an `E` instance, you'll *not* create a clone of `E`, but that was never the intention. – Andreas Dolk May 08 '11 at 20:32
0

Here an example to the answers from Peter (not tested, may need some syntax checks):

class A <E> {  // class A has objects of E

    int x;

    private B<T> next // a object of inner class

    class B<T> implements Cloneable {
        public B<T> clone() {
           try {
              B<T> klon = (B<T>) super.clone();
              // TODO: maybe clone the array too?
              return klon;
           }
           catch(CloneNotSupportedException) {
              // should not occur
              throw new Error("programmer is stupid");
           }
        }
        // an inner class having objects of type T

        T[] elements = (T[]) Object[x];
        // has other stuff including many objects  
    }

 public A<E> func ( B<E> val ){
     B<E> clone = val.clone();
     // more code
 }
Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210