Java: how to make a protective copy when you only have an interface

If an object refers to another object, I know that it might be a good idea to make a copy of the passed object to preserve encapsulation. But what if the whole object knows about the passed object, is that it implements the interface?

For example, if I have an object that accepts an implementation of FilenameFilter in its constructor, how can I make a protective copy of it when all I know about it is that it implements FilenameFilter? Do I have to resort to using reflection?

+4
source share
3 answers

It is best to deal with such a problem in order to make as many of your objects immutable as possible, that is, they cannot be changed after creation. If you need to modify them, you make a new one, leaving the original untouched.

It is also better for multithreading.

Variable objects are not considered "best practice" as a general rule. You cannot completely eliminate them, but, as Josh Bloch says, they prefer immutability.

Speaking of this, there is no real way to make a deep copy (what you need) in any guaranteed way. If you are simply passed in an interface, then your only options really reflect some form or make a copy for another object that implements the same interface (if possible).

+6
source

First of all, it is not always a good idea to make a protective copy. You only want to do this with mutable classes that cannot enforce the contract that your business logic requires (such as collections).

Your perfect example. FilenameFilter is immutable - nothing can change it through this interface. Feel free to transfer it as you wish. The only potential problem is threads, and this is a pretty rare problem.

A more general solution (for classes that are actually a problem similar to collections) would be to wrap the collection in the class, rather than copying it. If you put it in a business logic class, you can restrict access until you make sure that it does not violate your business logic rules, and then feel free to pass it around.

You will notice that the JDK almost never misses collections. This is intentional, and the exact reason for the "Copy" template that you are considering. Typically, the JDK passes an array, and most collections have a fairly simple way to generate copies of their contents for transfer.

Copying an object is actually extremely rare - collections and arrays are primary. Most other objects can protect themselves quite well, even if they are designed with half sticking.

+2
source

I'll start by carefully thinking about whether a protective copy is really necessary. If this is not a security issue, then it sounds as if a protective copy in this case is not absolutely necessary.

Then, assuming a copy is strictly necessary, I would define an additional FileFilter interface that defines a copy method with the appropriate semantics. Use this interface instead of the FileFilter in the constructor you specify, pass the FileFilters that implement the interface, and arrange for the above constructor to call the copy method at the appropriate time.

(Alternatively, you can use Object.clone() depending on the structure of the application package.)

0
source

All Articles