New instance of an object referenced by an interface in Java - java

I am working on a JDK6 project.
I have a pojo like:
public class MyPojo implements serializable {
private List<Integer> ids;
public List<Integers> getIds() {
return ids;
}
public List<Integers> setIds(List<Integer> ids) {
// idsCopy = copy of ids; // how can I do it?
this.ids = idsCopy;
}
}
I'd like to store a copy of the parameter ids passed in the setter, but I don't want to specialize it in the setId method signature by declaring the reference as a particular implementation of the List interface: depending on where the pojo is used, ids could be either a LinkedList, or an ArrayList, etc.
I'd like to keep the same implementation of the ids parameter.
How can I do the copy?
The first thing I thought was: ids.getClass().newInstance(), but it needs to be surrounded by a try/catch block for InstantiationException and IllegalAccessException, in particular because I am not sure that the actual implementation of ids has an empty constructor. Is there something more immediate?
Update
In this case the most common, straightforward and reasonable thing to do is avoiding making a copy and let who will use the class MyPojo passing a copy of the object to set, for instance:
List<Integer> ls = new Arraylist<>();
MyPojo pj = new MyPojo();
pj.setIds(ls.clone()); // or using copy constructor or anything else..
At the beginning I had the idea to do like this:
public <T extends List<Integer> & Cloneable> void setIds(T ids) {
this.ids = ids.clone();
}
enforcing using a class implementing also Cloneable but the javadoc of Cloneable interface explains very good why this is not intended to work (and also why reflection on clone would not too):
A class implements the Cloneable interface to
indicate to the method that it
is legal for that method to make a
field-for-field copy of instances of that class.
Invoking Object's clone method on an instance that does not implement the
Cloneable interface results in the exception
CloneNotSupportedException being thrown.
By convention, classes that implement this interface should override
Object.clone (which is protected) with a public method.
See for details on overriding this
method.
Note that this interface does not contain the clone method.
Therefore, it is not possible to clone an object merely by virtue of the
fact that it implements this interface. Even if the clone method is invoked
reflectively, there is no guarantee that it will succeed.
At the end, regardless the context, the answer to my question
Is there something more immediate?
is "no", most probably because there should not be the need to do it...
..even though..
https://rules.sonarsource.com/java/type/Vulnerability/RSPEC-2384

Is there something more immediate?
There are two possible ways to do this:
The method you proposed: use reflection to invoke the no-args constructor create a new empty list, and then use List::addAll to copy the elements to the new list.
Use the Object::clone method to create the copy.
Either approach (if it works!) will create a list object of the same type as the original. But neither method is guaranteed to work for all possible List classes.
The reflective approach fails if the list implementation class has no usable / accessible no-args constructor.
The clone approach fails if the list implementation class doesn't override Object::clone appropriately.
Note that these are not hypothetical concerns. A list implementation class may be deliberately designed to prevent programs making clones of the list. For example, there may be some relationship between the list and (say) a database query result set, such that cloning makes no sense.
But the flip-side is that if the library designer didn't provide a no-args constructor or a clone override, they probably did it for a good reason.
Finally, it is questionable that you should be trying to do this at all. There is no obvious reason for your MyPojo classes ids property to use the same List class as the original argument. This is actually making the behavior MyPojo class dependent on the behavior of the supplied list. I would argue that this is a bad thing because you are weakening the abstraction boundary for your MyPojo class.

As you have said it yourself:
The first thing I thought was: ids.getClass().newInstance(), but it
needs to be surrounded by a try/catch block for InstantiationException
and IllegalAccessException, in particular because I am not sure that
the actual implementation of ids has an empty constructor. Is there
something more immediate?
How will you be able to construct an instance of the underlying class when you don't even know what the constructor looks like? Say through reflection, you know what a (there could be more than one) constructor looks like, you still have to worry about things like:
Private vs Internal/Package-Private vs Public - How do you handle each case? Some implementations of List such as the ones found in the guava library use the builder pattern to construct the collection and therefore make the constructor private.
Number of constructor arguments - If more than one, how do you construct the rest?
Exceptions thrown by the constructor - How do you catch them all? Don't say "catch Exception" because you may miss Throwable.
Multiple constructors - How do you decide which one to call?
Many more corner cases to deal with...
You should adopt the KISS (Keep It Simple Soldier) principle as well as the SoC (Separation of Concerns) principle. Keep it simple and you will be rewarded. Let the person using the Pojo decide how they want to retrieve the list. As long as you make it clear (through documentation) what the method does, it is up to the user to make rational decisions as to how they use that method.
If they do something like:
LinkedList<Integer> myIds = ...;
myPojo.setIds(myIds);
then let them decide how to retrieve the ids; They can either cast the returned type or make a copy.
If you made it clear in the documentation that the list is copied, then the person using this POJO should know to make a copy as a LinkedList when they retrieve it, otherwise it should be safe for them to cast the list to a LinkedList.
I would still argue that even the above is not simple enough. The simplest thing to do (and this is what is widely accepted) is to use the most general type for the work needed. If you need a Mapping type, use Map, not HashMap or List/Set of tuples; If you need a unique collection, use Set, if you need a general collection, use List, etc.

You can use Arrays.asList for that e.g.
public void setIds(List<Integer> ids) {
this.ids = Arrays.asList(ids.toArray(new Integer[ids.size()]));
}
this should work for Java 1.6

Related

Methods That Return an Object of an Interface Type

All beginners like myself, always get confused to see a method returns an object of an interface type, because interfaces have abstract methods, thus cannot be instantiated.
I finally figured out a way to understand this:
((when we say that a method returns an object of an interface type, we are actually implicitly saying that the method in fact returns an object/instance of some class that implements that interface, but in most cases that class is unknown because it is declared as anonymous in the implementation of the method. Thus, we refer to the returned object as being of that interface type.)).
Is this explanation correct ?
"...when we say that a method returns an object of an interface type, we are actually implicitly saying that the method in fact returns an object/instance of some class that implements that interface..." - It is correct, but we are saying it explicitly.
The second part of your definition is quite not correct, as #Jon Skeet pointed out. Applying anonymous class in the implementation is a very specific case. Generally, returning an interface gives you more freedom:
It is possible to change implementation of the method to return another object that implements the same interface, without changing code that uses this method.
You leave possibility for extending classes to override the method, so that it returns another object that implements the same interface. Here you can actually change the return type. If method of the base class returned concrete class, e.g., ArrayList, overridden method would have to also return ArrayList or its subclass.
The rule of thumb is the following. If concrete class implements an interface and there is no benefit in returning a concrete class object, e.g., ArrayList, return an interface - List, Collection. This will enhance maintainability of your code, i.e., the code will be easier to change in future.
It's my birthday at the end of this month, so I've added a new method to all my friends and family:
public Present givePresent{
//code to select an appropriate and sufficiently expensive present
return present;
}
There's two things I could do here. I could write a Present class and ensure that all possible presents extend it. But we could run in to all sorts of problems here: BatmanComic already inherits from ComicBook for example, so we'd have to move further and further up the tree until Present is basically indistinguishable from Object. The other way is to look at what is actually happening here. I'm looking to receive something that fits in to a specific category and, in short, Java has two ways of doing that. Inheritance and Interfaces. Creating Present as an interface is achieving exactly the same goal as creating it as an abstract superclass but avoids all problems of multiple inheritance. This way all I have to do is write an interface:
public interface Present{
}
and make sure all the socks and books and whatever implement that.

How to subclass Guava's ImmutableList?

When I try to implement my own ImmutableList (actually a wrapper that delegates to the underlying list) I get the following compiler error:
ImmutableListWrapper is not abstract and does not override abstract method isPartialView() in com.google.common.collect.ImmutableCollection
But in fact, it seems to be impossible to override isPartialView() because it is package protected and I'd like to declare the wrapper in my own package.
Why don't I simply extend ImmutableCollection? Because I want ImmutableList.copyOf() to return my instance without making a defensive copy.
The only approach I can think of is declaring a subclass in guava's package which changes isPartialView() from package-protected to public, and then having my wrapper extend that. Is there a cleaner way?
What I am trying to do
I am attempting to fix https://github.com/google/guava/issues/2029 by creating a wrapper that would delegate to the underlying ImmutableList for all methods except spliterator(), which would it override.
I am working under the assumption that users may define variables of type ImmutableList and expect the the wrapper to be a drop-in replacement (i.e. it isn't enough to implement List, they are expecting an ImmutableList).
If you want your own immutable list but don't want to implement it, just use a ForwardingList. Also, to actually make a copy, use Iterator as parameter for the copyOf. Here's a solution that should fulfill all your requirements described in the question and your answer.
public final class MyVeryOwnImmutableList<T> extends ForwardingList<T> {
public static <T> MyVeryOwnImmutableList<T> copyOf(List<T> list) {
// Iterator forces a real copy. List or Iterable doesn't.
return new MyVeryOwnImmutableList<T>(list.iterator());
}
private final ImmutableList<T> delegate;
private MyVeryOwnImmutableList(Iterator<T> it) {
this.delegate = ImmutableList.copyOf(it);
}
#Override
protected List<T> delegate()
{
return delegate;
}
}
If you want different behavior than ImmutableList.copyOf() provides, simply define a different method, e.g.
public class MyList {
public static List<E> copyOf(Iterable<E> iter) {
if (iter instanceof MyList) {
return (List<E>)iter;
return ImmutableList.copyOf(iter);
}
}
Guava's immutable classes provide a number of guarantees and make a number of assumptions about how their implementations work. These would be violated if other authors could implement their own classes that extend Guava's immutable types. Even if you correctly implemented your class to work with these guarantees and assumptions, there's nothing stopping these implementation details from changing in a future release, at which point your code could break in strange or undetectable ways.
Please do not attempt to implement anything in Guava's Imutable* heirarchy; you're only shooting yourself in the foot.
If you have a legitimate use case, file a feature request and describe what you need, maybe it'll get incorporated. Otherwise, just write your wrappers in a different package and provide your own methods and guarantees. There's nothing forcing you, for instance, to use ImmutableList.copyOf(). If you need different behavior, just write your own method.
Upon digging further, it looks like this limitation is by design:
Quoting
http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableList.html:
Note: Although this class is not final, it cannot be subclassed as it has no public or protected constructors. Thus, instances of this type are guaranteed to be immutable.
So it seems I need to create my wrapper in the guava package.

If I need serializable should i use concrete List (e.g. ArrayList) or (Serializable)List?

We have a discussion in office and cannot understand which approach is better
I have a class (SomeClass) with some method which receives Serializable object. The signature is following:
public void someMethod(Serializable serializableObject){
...
}
And I need to call this method from another class, but I should provide it with some List as fact parameter. There are two different approaches
1. Serializable
private SomeClass someClass;
public void doSomething() {
List<String> al = new ArrayList<String>();
al.add("text");
someClass.someMethod((Serializable)al);
}
2. ArrayList
private SomeClass someClass;
public void doSomething() {
ArrayList<String> al = new ArrayList<String>();
al.add("text");
someClass.someMethod(al);
}
Benefit of the first example is that it adheres to the java’s best practices which says: use interface instead of concrete realization for reference type and any programmer while reading that source will understand that we don't need special behavior of the ArrayList. And the only place we need it's serializable behavior we are adding this behavior by casting it to the Serializable interface. And programmer can simply change this current realization of the List to some other serializable realization, for example, LinkedList, without any side affect on this element because we use interface List as it`s reference type.
Benefit of the second example is that we refer to ArrayList as to class which have not only List behavior but also Serializable behavior. So if someone looked at this code and tried to change ArrayList to List he would receive a compile time error which would reduce time for programmer to understand what is going on there
UPDATE: we can't change someMethod signature. It came from a third-party company and we use it not only for Serializable Lists but also for Strings, Integers and some other Serializable objects
You should use an interface when all you need is the methods an interface provides. (this is most cases) However, if you need more than one interface, you can use generics, but the simplest approach is to use the concrete type.
It's better to define ArrayList because this combines two interfaces - List + Serializable. You need both of them in one place.
It doesn't matter that much, but not that using interfaces should be applied more strictly for return types, and less strictly for local variables.
I would change the signature of the someMethod so that it reflects what it requires from the invoker of the method:
public class SomeClass {
public <T extends List<? extends Serializable> & Serializable> void someMethod(T t) {
}
public static void main(String[] args) {
SomeClass test = new SomeClass();
test.someMethod(new ArrayList<String>()); //Works
test.someMethod(new ArrayList<Image>()); //Compile time error, Image is not Serializable
List<String> l = null;
test.someMethod(l); //Compile time error
}
}
The signature of someMethod now says that you must invoke it with something that is a List, and that is Serializable, and contains elements that are Serializable
In this case, I would just use List, and not worry that the compiler cannot guarantee that your object is serializable (it most likely will be anyway, if you've done things right elsewhere).
Note that methods of the following type (which accept a Serializable parameter) provide a false sense of security, because the compiler can never guarantee that the entire object graph which needs to be serialized will actually be serializable.
public void write(Serializable s);
Consider an ArrayList (serializable) which contains non-serializable objects. The signature may as well just be:
public void write(Object o);
And then you don't have to worry about all the extraneous casting.
Also consider that, although you cannot change the signature of the API you are using, you can very easily create a wrapper API which has a different signature.
1 is generally the right thing to do. However in this case, my opinion would to be bend that and declare it as ArrayList<>. This avoids the cast and guarantees that someone can't change the implementation of the List to one that isn't Serializable.
You can't do (1) because you're not free to change the List implementation type arbitrarily, which is the whole idea of doing that. You can only use a List implementation that implements Serializable. So you may as well express that in the code.

Implementing clone on a LinkedList

I am trying to implement a clone() method on a DoubleLinkedList. Now, the problem is that implementing it by "the convention" is a lot more troublesome than just creating a new DoubleLinkedList and filling it with all the elements of my current DoubleLinkedList.
Is there any inconvenient I am not seeing when doing that?
Here is my current approach:
#Override
public DoubleLinkedList<T> clone() {
DoubleLinkedList<T> dll = new DoubleLinkedList<T>();
for (T element : dll) {
dll.add(element);
}
return dll;
}
Here is what it would be by the convention:
#Override
public DoubleLinkedList<T> clone() {
try {
DoubleLinkedList<T> dll = (DoubleLinkedList<T>)super.clone();
//kinda complex code to copy elements
return dll;
} catch (CloneNotSupportedException e) {
throw new InternalError(e.toString());
}
}
As you correctly point out, the convention is to always call super.clone() in the beginning of an implementation of clone(). From the API docs on Object#clone():
By convention, the returned object should be obtained by calling super.clone. If a class and all of its superclasses (except Object) obey this convention, it will be the case that x.clone().getClass() == x.getClass().
Your first attempt (without using super.clone()) has the following problem:
Suppose I have
class IntDoubleLinkedList extends DoubleLinkedList<Integer> implements Cloneable
(and that IntDoubleLinkedList does not bother to override clone()) and I run the following code:
IntDoubleLinkedList idll = new IntDoubleLinkedList();
IntDoubleLinkedList idll2 = (IntDoubleLinkedList) idll.clone();
What will happen? The clone method of your DoubleLinkedList will be executed, which, if it doesn't go through super.clone(), returns an instance of DoubleLinkedList which in turn can not be casted to an IntDoubleLinkedList. A ClassCastException will be thrown!
So how does super.clone() solve this issue? Well, if everybody stick to the convention of calling super.clone() in an overriden clone method, Object.clone() will eventually be called, and this implementation will create an instance of a proper type (IntDoubleLinkedList in this case)!
As others have explained, if you're going to override clone you should obey its contract.
If you like the way you currently have it, just make DoubleLinkedList not Cloneable and turn your implementation into a copy constructor or static factory method. A static factory method has the added benefit of providing a bit of type inferencing for generic type arguments, too.
P.S. LinkedList is a doubly-linked list.
If you do it by creating a new list and adding all the elements from the source, if you then do something like:
DoubleLinkedList<Foo> l1 = new DoubleLinkedList<Foo>();
l1.add (new Foo(params));
DoubleLinkedList<Foo> l2 = l1.clone();
Foo foo = l2.get(0);
foo.setProperty("new Value");
foo.property will be "new value" in both lists (the same the other way around; if you change it in l1, changes will appear in l2). The correct way would be to actually clone every element and the add the clone to ensure the lists are independent. Take note that this only happens if you change properties of the elements, not if you add, move, delete them from the list.
Edit: just realized that since it's a linked list, the next/previous elements are properties of the element, so even adding, deleting, will affect both list.
The reason the "convention" is to call super.clone() is to ensure the ultimate type of the cloned object matches the object that is being cloned. For example if you instantiate your own new DoubleLinkedList in the clone() method, well that's nice for now, but later if a subclass fails to override clone() it will end up returning a clone that is a DoubleLinkedList instead of its own class. (It'll also fail to clone its additional fields, if any, probably! so there are larger issues.)
In that sense, the conventional method is preferred, and it is indeed clunky.
Both implementations, however, have a similar problem: you're not deep-copying the data structures. The clone is only a shallow cop. This is probably not what the caller expects. You would need to go through and replace each value in the DoubleLinkedList with a clone of the value, and likewise for other non-primitive fields.
In that sense, the conventional method is going to give the wrong result here! You need a third way. Your first method probably just about works, except that you need to add element.clone() for example.

How can I create a copy of my data type I created in Java?

If I have a class:
public class MyType
{
private List<Integer> data;
private boolean someFlag;
public MyType(List<Integer> myData, boolean myFlag)
{
this.data = myData;
this.myFlag = someFlag;
}
}
Now, if I create an instance of MyType, how do I do a deep copy of it? I don't want the new object to point to the old reference, but an entirely new instance.
Is this a case when I should implement the Cloneable interface, or is that a used for shallow copies?
I can't just do:
MyType instance1 = new MyType(someData, false);
MyType instance2 = new MyType(instance1.getData(), instance1.getFlag());
I'm concerned about new instances of MyType pointing to the same reference for its "data" variable. So I need to copy it entirely.
So, if I have an existing object:
MyType someVar = new MyType(someList, false);
// Now, I want a copy of someVar, not another variable pointing to the same reference.
Can someone point me in the right direction?
First: Your code sample has some naming issues: is it myFlag or someFlag?
Many developers will abstain from Cloneable and just create a copy constructor for a class when deep copies are needed:
public class MyType {
private boolean myFlag;
private List<Integer> myList;
public MyType(MyType myInstance) {
myFlag = myInstance.myFlag;
myList = new ArrayList<Integer>(myInstance.myList);
}
}
Copy constructors quite common, and can be found in many of the Collections implementations. I prefer them over implementing Cloneable for reasons of clarity. It's also worth noting that even the mighty Joshua Bloch says in Effective Java (second edition page 61) that copy constructors have many advantages over Cloneable/clone.
They don't rely on a risk-prone
extralinguistic object creation
mechanism
They don't demand unenforceable
adherence to thinly documented
conventions
They don't conflict with the proper
use of final fields
They don't throw unnecessary checked
exceptions
They don't require casts.
If you don't own his book, get it!
You can make all classes in your object graph implement Cloneable and provide manual cloning. Since in your case it's only one list (i.e. a very small object graph), you'd better use the copy-constructor:
List newData = new ArrayList(data)
But remember that in that case the contents of the list will still be the same objects, so it won't be a real deep copy. In your case these are Integers, so no big deal. But if you change it, be careful.
If you need to clone bigger object graphs, then, in two steps:
make your class implement the Serializable interface
use apache commons-lang SerializationUtils.clone(yourObject)
It makes a deep copy using the serialization mechanisms in java.
Alternatively, you can use this library - it does not require the Serializable interface and makes deep copies using reflection.
You should implement Cloneable. You define what a "copy of your type" exactly means. Sometimes it is required to have a type containing a field whose content remains the same within multiple copies (==reference to the same object in all copied instances)
You have to take care on your own that all the fields are actually copied to a new instance. Primitive datatypes like int, long, etc. are copied as they are directly stored, they never contain references.
If you have fields to object references of what type ever, you need to find a mechanism to create a copy of each of them.
Generally, you do have a shallow copy after calling .clone(). If (and only if) all the types used in your class are themselves implementing Cloneable correctly, you get a fully recursive deep copy.
According to JavaDoc (Object.clone()) Clonable means the following:
x.clone() != x && x.clone().getClass() == x.getClass() && x.clone().equals(x)
Remember that this is the general intent, and this is not a mandatory contract
your class MyType must implement Cloneable. then you can call someVar.clone()
Implement ICloneable

Categories

Resources