Immutable classes in java - java

Is it required to make the fields of an Immutable class private as if they are marked as final , can not be changed ?
I mean isn't it enough to just mark the fields as final ?
(I know that it's not necessary for an immutable class to have final fields but it's advisable to have it for compile time check for the class internally.)

No this is not enough.
Consider this example:
final class ImmutableClass {
private final List<String> data;
public ImmutableClass(final List<String> data) {
this.data = data;
}
public List<String> getData() {
return data;
}
}
This class is final so cannot be extended. It's data field is final so cannot be changed after it is assigned.
But:
final ImmutableClass immutableClass = new ImmutableClass(data);
immutableClass.getData().add("Some other value");
Oops.
So to make a class truly immutable all fields should also be immutable classes, or have defensive copies.
For example, to correct the issues about you would need to do this:
final class ImmutableClass {
private final List<String> data;
public ImmutableClass(final List<String> data) {
this.data = new ArrayList<>(data);
}
public List<String> getData() {
return Collections.unmodifiableList(data);
}
}
And this only works because String is immutable. If you had, for instance, a List<Date> you would also need to copy the individual Date objects.

Having private variables accessed through getters gives you more freedom with the implementation of the class. You can, for example, replace a trivial getter with an implementation which calculates or retrieves the value on access or caches the result.
Another reason to keep fields as private even when they are final is when the field is a mutable object. In that case the object can be changed even though it is final which is usually not what you want. Here is an example of a presumably immutable class with a public final field of the mutable Date class.
class DateHolder {
public final Date date;
DateHolder(Date date) {
this.date = date:
}
}
// ...
DateHolder holder = new DateHolder(Date.now());
// this doesn't work because date is final:
//holder.date = new Date(2013, 11, 23);
// but this works even though date is final:
holder.date.setYear(2013);

final fields can only be assigned to from within the constructor. Therefore, making fields final is enough to make them immutable after construction. Assigning pointers to mutable objects to them is a different story.

Related

How to map class fields to another class?

I'm not looking for the best way to do this, but rather for any way to do what i need while adhering to the DRY principle.
Let's say I have a class Source as follows. Source contains thirty strings.
class Source {
private String sourceAttrOne = "sourceValueOne";
private String sourceAttrTwo = "sourceValueTwo";
...
private String sourceAttrThirty = "sourceValueThirty";
}
This information is to be used to create a new object of class Destination. 25 of Destination's attributes have a name in a similar format (but not the same name). 10 of these are Strings, while 5 are Dates, and 5 are Integers. The last 5 fields, however, are totally different.
class Destination {
private String AttrOne;
...
private Date AttrSixteen;
...
private Integer AttrTwentyOne;
...
// Last 5 fields are different
private SomeOtherClass someOtherName;
private TheBestClass imAlsoSpecial;
// Standard getters and setters
}
For the 25 "normal" attributes, I need to use a helper method to get from the source value to the result. The helper method used depends on the destination type:
destination.setAttrOne(getResultingString(source.getSourceAttrOne()));
destination.setAttrSixteen(getResultingDate(source.getSourceAttrSixteen());
destination.setAttrSeventeen(getResultingDate(source.getSourceAttrSeventeen()/*, custom Date format for AttrSeventeen */));
The remaining 5 attributes need custom (individual) logic.
Any pointers in the right direction would be much appreciated, I don't need a complete solution :)
N.B.: I'm probably totally mistaken, so nevermind me if that's the case.
I also haven't unlocked comments yet, while it would be more likely the best; sorry for the inconvenience.
If the 1st to 15th attributes are String, then supposedly, you can simply affect them to the corresponding attributes, or clone them first, if you prefer.
For the 16th to 21th(?), which are dates, you might be able to use DateFormat's parse(String) method; although, I'm clueless on how to help the compiler to get the used format or if it can do it properly by itself.
For the 22th to 27th(?), the Integers, you should be able to use Integer's parse(String) method, or possibly through Double's and then convert back to an Integer or an int.
You can try Reflection for similar targets.
Something like:
public void fillFieldsHelper(Object source) {
List<Field> sourceFields = source.getClass().getDeclaredFields();
or
Field valueOne = source.getClass().getDeclaredField("sourceAttrOne");
System.out.println(valueOne.getName());
System.out.println(valueOne.getType());
...
Object value = valueOne.get(source);
Field attrOne = this.getClass().getDeclaredField(valueOne.getName().replace("source",""));
switch (attrOne.getType().getName()) {
case "java.lang.Integer":
attrOne.set(this, Integer.valueOf(value));
break;
default:
attrOne.set(this, value);
}
...
etc.
I can't say that Reflection is elegant but it's useful in many cases.
So in your case you have several possibilities.
Create Object from Object
The easiest but maybe not the nicest solution (depending on your further process/requirements) is to have a constructer which has the need Object as parameter.
public class Source {
private String sourceAttrOne;
private String sourceAttrTwo;
// further class attributes....
// getters (& setters)
}
public class Destination {
private String attrOne;
private String attTwo;
public Destination(Source source) {
this.attrOne = source.getSourceAttrOne;
this.attrTwo = source.getSourceAttrTwo;
// etc..
}
}
User Builder Pattern
The problem in the solution above is, that depending of which fields are required for creating the Destination.class the constructer is going to have a lot of parameters. In addition, if you have to change your constructer in the future (e.g. additional required fields), you have to create a new constructer or change the already existing one (which implies you have to change all the current usages of that).
Therefore to hold the DRY, I would recommend the Builder Patter.
public class Destination {
private String attrOne;
private String attTwo;
private String attThree; // attribute which comes not from any other source class and is e.g. not a required field
private Destination() {
// should not be accessible
}
public static class Builder {
private String attrOne;
private String attTwo;
private String attThree;
private Builder() {
// do nothing
}
public static Builder create(Source source) {
Builder builder = new Builder();
builder.attrOne = source.getSourceAttrOne();
builder.attrTwo = source.getSourceAttrTwo();
return builder;
}
public Builder attThree(String attThree) {
this.attThree = attThree;
return this;
}
public Destination build() {
Destination destination = new Destination();
destination.attrOne = builder.attrOne;
destination.attrTwo = builder.attrTwo;
destination.attrThree = builder.attrThree;
//add several validations e.g. assert destination.attrOne != null
return destination;
}
}
}
To create a Destination.class with Source.class you can do following:
Destination.Builder.create(source).build();
For having different Types e.g. Source.sourceAttrOne is a String and the in the Destination.attrOne is a Date, you just have to adjust the Destination.class.
public class Destination {
private LocalDate attrOne;
// ...
private Destination() {}
public static class Builder {
private String attrOne;
// ...
private Builder() {}
public static Builder create(Source source) {
Builder builder = new Builder();
builder.attrOne = LocalDate.parse(source.getSourceAttrOne());
// ...
return builder;
}
public Destination build() {
Destination destination = new Destination();
destination.attrOne = builder.attrOne;
// ...
return destination;
}
}
}

Serialization with singleton design pattern

I have a problem with serialization of a class using the singleton pattern. First let me introduce the code:
import java.io.ObjectStreamException;
import java.io.Serializable;
import org.ejml.simple.SimpleMatrix;
public class Operation implements Serializable {
private static final long serialVersionUID = 1L;
private final static int CONSTANT = 10;
private SimpleMatrix data;
private Long timestamp;
private static Operation instance = new Operation ();
private Operation () {
data = new SimpleMatrix(1, CONSTANT);
}
protected static Operation getInstance() {
return instance;
}
//Hook for not breaking the singleton pattern while deserializing.
private Object readResolve() throws ObjectStreamException {
return instance;
}
protected void setData(SimpleMatrix matrix) {
this.data = matrix;
}
protected SimpleMatrix getData() {
return data;
}
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
}
I have three problems with it hoping that somebody can help me:
As far as I know, static fields are no serialized. So if I deserialize is my final static field CONSTANT set to 10? If not, how can I make this? This is very important.
As you can see, in the constructor a new matrix is created. If I deserialize, is my data overwritten by this constructor? For deserialization I want the data of the serialized version and not a new matrix. The constructor I only need the first time before serialization to instantiate the object.
Before I serialize I will set the field timestamp to the time of serialization. After deserialization I would like to compare this field with the timestamp of some files (to see if files have changed since serialization). What sort of timestamp should I use for both the serialization time and the last modified time of files so that I can easily compare?
The static constant is associated with the class, so serialization and deserialization of your instance won't impact it at all.
For the deserialization to work, you need to set the singleton's data to the deserialized instance data:
private Object readResolve() throws ObjectStreamException {
instance.setData(getData());
return instance;
}
The timestamp can stay as a Long, that's fine. Use System.currentTimeMillis(), you'll be able to compare with a File object lastModified() date. Just set the field when you serialize:
private void writeObject(java.io.ObjectOutputStream out)
throws IOException{
timestamp=System.currentTimeMillis();
out.defaultWriteObject();
}
A test I've made to be sure of what I say, using a String instead of a matrix as in your code:
public static void main(String[] args) throws Exception {
Operation op=getInstance();
op.setData("test1");
byte[] ds=serialize();
System.out.println(new Date(getInstance().timestamp));
op.setData("test2");
deserialize(ds);
System.out.println(getInstance().getData());
}
This gives me the current date and test1, since the deserialize instance has overriden the current instance. serialize and deserialize simply convert between the instance and bytes.
I would suggest that you adopt the Enum Singleton approach for implementing Singletons, as handling Serialization would be done for free. In your case it would be
public enum Operation {
INSTANCE;
// No need to handle Serialization
}
Quoting Joshua Bloch in Effective Java "a single-element enum type is the best way to implement a singleton."
There are plenty benefits to this approach, you can find out here
And also For instance control, prefer enum types to readResolve

Best way to set an erray to empty within the parameters of another class

This class is where I want to call the arrays and set the arrays to empty within the parameters
public class ElectronicsEquipmentSupplier {
private int currentMonth;
private int currentYear;
private String rangeOfProducts;
private CustomerDetailsList details; //Contains the customer details array
private PurchaseOrderList pal; //Contains the purchase array
public ElectronicsEquipmentSupplier(int currentMonth, int currentYear,
String rangeOfProducts ) {
this.currentMonth = currentMonth;
this.currentYear = currentYear;
this.rangeOfProducts = rangeOfProducts;
}
}
This is the class where the array is created. It pulls information from a separate class called PurchaseOrder and then sets the list.
public class PurchaseOrderList {
private ArrayList<PurchaseOrder> purchaseCollection;
public PurchaseOrderList() {
purchaseCollection = new ArrayList<PurchaseOrder>();
}
The CustomerDetailsList class is essentially the same. Just not sure as to the best way to set the array to empty when called in the ElectronicsEquipmentSupplier.
Simply wrap the collection's own clear() method with a publicly-accessible method in your PurchaseOrderClass:
public class PurchaseOrderList {
private ArrayList<PurchaseOrder> purchaseCollection;
public PurchaseOrderList() {
purchaseCollection = new ArrayList<PurchaseOrder>();
}
//THIS IS THE IMPORTANT PART
public void clearPurchaseCollection() {
purchaseCollection.clear();
//You could also accomplish the same thing by reinitializing the list:
//purchaseCollection = new ArrayList<PurchaseOrder>();
}
}
Note however, that calling new PurchaseOrderList() already guarantees an empty purchaseCollection list, since you initialize it in the constructor that way.
So the only time you would need to call clearPurchaseCollection() is if you are reusing this object and want to clean it out first. Depending on the rest of your application, that may be necessary, but it may also just be simpler to throw away that instance and create a new PurchaseOrderList(). Totally depends on the situation.

How to use Java Enums being DRY with only a single parameter different between instantiations?

I'm trying to figure out if there is a clean way of doing this. I want to design an ENUM to maintain a list of constant values for different components in my application. Each enum would have the same configuration and same parameters, but would differ at the very least by component name.
In a normal Java class, I could build all the basic logic/code in a base abstract class, and have each component constants extend the abstract class and populate only its own pertinent information. However, Java enums do not allow extending existing classes.
Is there something I can do to avoid having to either push all my constants in a single Enum (ugggg!) or recreate the same enum class each time for each differing component? Definitely not DRY in that case, but I do not know how to avoid the issue.
For a quick use-case example off the top of my head. Say I want to keep a list of all my request mappings in an Enum for use elsewhere in my application. Fairly easy to design an enum that says:
public enum RequestMapping {
INDEX("index"),
GET_ALL_USERS( "getAllUsers");
private String requestMapping = "/users";
private String path;
RatesURI( String path ){
this.path = path;
}
public String getRequestMapping(){
return requestMapping;
}
public String getPath(){
return path;
}
public String getFullRequestPath(){
return requestMapping + "/" + path;
}
}
It becomes easy to use RequestMapping.GET_ALL_USERS.getFullRequestPath().
Now if I want to create this enum on a per-controller basis, I would have to recreate the entire Enum class and change the "requestMapping" value for each one. Granted, this enum has nearly no code in it, so duplicating it would not be difficult, but the concept still remains. The theoretical "clean" way of doing this would be to have an abstract AbstractRequestMapping type that contained all the methods, including an abstract getRequestMapping() method, and only have the extending Enums implement the controller-specific getReqeuestMapping(). Of course, since Enums cannot be extended, I can't think of a non DRY way of doing this.
Have you considered extending a class that takes Enum as a generic parameter? It is an amazingly flexible mechanism.
public class Entity<E extends Enum<E> & Entity.IE> {
// Set of all possible entries.
// Backed by an EnumSet so we have all the efficiency implied along with a defined order.
private final Set<E> all;
public Entity(Class<E> e) {
// Make a set of them.
this.all = Collections.unmodifiableSet(EnumSet.<E>allOf(e));
}
// Demonstration.
public E[] values() {
// Make a new one every time - like Enum.values.
E[] values = makeTArray(all.size());
int i = 0;
for (E it : all) {
values[i++] = it;
}
return values;
}
// Trick to make a T[] of any length.
// Do not pass any parameter for `dummy`.
// public because this is potentially re-useable.
public static <T> T[] makeTArray(int length, T... dummy) {
return Arrays.copyOf(dummy, length);
}
// Example interface to implement.
public interface IE {
#Override
public String toString();
}
}
class Thing extends Entity<Thing.Stuff> {
public Thing() {
super(Stuff.class);
}
enum Stuff implements Entity.IE {
One,
Two;
}
}
You can pass the nature of your implementation up to the parent class in many different ways - I use enum.class for simplicity.
You can even make the enum implement an interface as you can see.
The values method is for demonstration only. Once you have access to the Set<E> in the parent class you can provide all sorts of functionality just by extending Entity.
I will probably split the responsibilities into two parts:
Logic about how a request is structured, and put that into an immutable class.
Actual configurations of each request, stored in enums
The enum will then store an instance of that class, you can add new methods to the class, without modifying the different enums, as long as the constructor remains the same. Note that the class must be immutable, or your enum will not have a constant value.
You can use it like the:
ServiceRequest.INDEX.getRequest().getFullRequestPath()
With these classes:
public interface RequestType {
Request getRequest();
}
public class Request {
private final String requestMapping;
private final String path;
RatesURI(String requestMapping, String path){
this.requestMappint = requestMapping;
this.path = path;
}
public String getRequestMapping(){
return requestMapping;
}
public String getPath(){
return path;
}
public String getFullRequestPath(){
return requestMapping + "/" + path;
}
}
public enum ServiceRequest implements RequestType {
INDEX("index"),
GET_ALL_USERS( "getAllUsers");
private final Request;
ServiceRequest(String path) {
request = new Request("users/", path)
}
public String getRequest{
return request;
}
}
I think what you should be asking yourself is really why you want to use enums for this. First we can review some of the points that make Java enumerated types what they are.
Specifically
A Java enum is a class that extends java.lang.Enum.
Enum constants are static final instances of that class.
There is some special syntax to use them but that is all they boil down to. Because instantiating new Enum instances is disallowed outside of the special syntax (even with reflection, enum types return zero constructors) the following is also ensured to be true:
They can only be instantiated as static final members of the enclosing class.
The instances are therefore explicitly constant.
As a bonus, they are switchable.
What it really boils down to is what it is about the enums that makes them preferable over a simpler OOP design here. One can easily create a simple RequestMapping class:
/* compacted to save space */
public class RequestMapping {
private final String mapping, path;
public RequestMapping(String mapping, String path) {
this.mapping = mapping; this.path = path;
}
public String getMapping() {
return mapping; }
public String getPath() {
return path; }
public String getFullRequestPath() {
return mapping + "/" + path;
}
}
Which can easily be extended to break down the repeated code:
public class UserMapping extends RequestMapping {
public UserMapping(String path) {
super("/users", path);
}
}
/* where ever appropriate for the constants to appear */
public static final RequestMapping INDEX = new UserMapping("index"),
GET_ALL_USERS = new UserMapping("getAllUsers");
But I assume there is something about enums that is attractive to your design, such as the principle that instances of them are highly controlled. Enums cannot be created all willy-nilly like the above class can be. Perhaps it's important that there be no plausible way for spurious instances to be created. Of course anybody can come by and write in an enum with an invalid path but you can be pretty sure nobody will do it "by accident".
Following the Java "static instances of the outer class" enum design, an access modifier structure can be devised that generally abides by the same rule set as Enum. There are, however, two problems which we can't get around easily.
Two Problems
Protected modifier allows package access.
This can easily be surmounted initially by putting the Enum-analog in its own package. The problem becomes what to do when extending. Classes in the same package of the extended class will be able to access constructors again potentially anywhere.
Working with this depends on how stringent you want to be on creating new instances and, conversely, how clear the design ends up. Can't be a whole mess of scopes just so only a few places can do the wrong thing.
Static members are not polymorphic.
Enum surmounts this by not being extendable. Enum types have a static method values that appears "inherited" because the compiler inserts it for you. Being polymorphic, DRY and having some static features means you need instances of the subtype.
Defeating these two issues depends on how stringent you want your design to be and, conversely, how readable and stable you want your implementation to be. Trying to defy OOP principles will get you a design that's hard to break but totally explodes when you call that one method in a way you aren't supposed to (and can't prevent).
First Solution
This is almost identical to the Java enum model but can be extended:
/* 'M' is for 'Mapping' */
public abstract class ReturnMapping<M extends ReturnMapping> {
/* ridiculously long HashMap typing */
private static final HashMap <Class<? extends ReturnMapping>, List<ReturnMapping>>
VALUES = new HashMap<Class<? extends ReturnMapping>, List<ReturnMapping>>();
private final String mapping, path;
protected Mapping(String mapping, String path) {
this.mapping = mapping;
this.path = path;
List vals = VALUES.get(getClass());
if (vals == null) {
vals = new ArrayList<M>(2);
VALUES.put(getClass(), vals);
}
vals.add(this);
}
/* ~~ field getters here, make them final ~~ */
protected static <M extends ReturnMapping> List<M>(Class<M> rm) {
if (rm == ReturnMapping.class) {
throw new IllegalArgumentException(
"ReturnMapping.class is abstract");
}
List<M> vals = (List<M>)VALUES.get(rm);
if (vals == null) {
vals = new ArrayList<M>(2);
VALUES.put(rm, (List)vals);
}
return Collections.unmodifiableList(vals);
}
}
Now extending it:
public final class UserMapping extends ReturnMapping<UserMapping> {
public static final UserMapping INDEX = new UserMapping("index");
public static final UserMapping GET_ALL_USERS = new UserMapping("getAllUsers");
private UserMapping(String path) {
super("/users", path);
}
public static List<UserMapping> values() {
return values(UserMapping.class);
}
}
The huge static HashMap allows almost all of the values work to be done statically in the superclass. Since static members are not properly inherited this is the closest you can get to maintaining a list of values without doing it in the subclass.
Note there are two problems with the Map. The first is that you can call the values with ReturnMapping.class. The map should not contain that key (the class is abstract and the map is only added to in the constructor) so something needs to be done about it. Instead of throwing an exception you could also insert a "dummy" empty list for that key.
The other problem is that you can call values on the superclass before the instances of the subclass are instantiated. The HashMap will return null if this is done before the subclass is accessed. Static problem!
There is one other major problem with this design because the class can be instantiated externally. If it's a nested class, the outer class has private access. You can also extend it and make the constructor public. That leads to design #2.
Second Solution
In this model the constants are an inner class and the outer class is a factory for retrieving new constants.
/* no more generics--the constants are all the same type */
public abstract class ReturnMapping {
/* still need this HashMap if we want to manage our values in the super */
private static final HashMap <Class<? extends ReturnMapping>, List<Value>>
VALUES = new HashMap<Class<? extends ReturnMapping>, List<Value>>();
public ReturnMapping() {
if (!VALUES.containsKey(getClass())) {
VALUES.put(getClass(), new ArrayList<Value>(2));
}
}
public final List<Value> values() {
return Collections.unmodifiableList(VALUES.get(getClass()));
}
protected final Value newValue(String mapping, String path) {
return new Value(getClass(), mapping, path);
}
public final class Value {
private final String mapping, path;
private Value(
Class type,
String mapping,
String path) {
this.mapping = mapping;
this.path = path;
VALUES.get(type).add(this);
}
/* ~~ final class, field getters need not be ~~ */
}
}
Extending it:
public class UserMapping extends ReturnMapping {
public static final Value INDEX, GET_ALL_USERS;
static {
UserMapping factory = new UserMapping();
INDEX = factory.newValue("/users", "index");
GET_ALL_USERS = factory.newValue("/users", "getAllUsers");
}
}
The factory model is nice because it solves two problems:
Instances can only be created from within the extending class.
Anybody can create a new factory but only the class itself can access the newValue method. The constructor for Value is private so new constants can only be created by using this method.
new UserMapping().values() forces the values to be instantiated before returning them.
No more potential errors in this regard. And the ReturnMapping class is empty and instantiating new objects in Java is fast so I wouldn't worry about overhead. You can also easily create a static field for the list or add static methods such as in solution #1 (though this would deflate the design's uniformity).
There are a couple of downsides:
Can't return the subtyped values List.
Now that the constant values are not extended they are all the same class. Can't dip in to generics to return differently-typed Lists.
Can't easily distinguish what subtype a Value is a constant of.
But it's true this could be programmed in. You could add the owning class as a field. Still shaky.
Sum Of It
Bells and whistles can be added to both of these solutions, for example overriding toString so it returns the name of the instance. Java's enum does that for you but one of the first things I personally do is override this behavior so it returns something more meaningful (and formatted).
Both of these designs provide more encapsulation than a regular abstract class and most importantly are far more flexible than Enum. Trying to use Enum for polymorphism is an OOP square peg in a round hole. Less polymorphism is the price to pay for having enumerated types in Java.

Regarding an immutable class

I have the following query , I was going through Java immutable class concept and come up with the following analysis..
All the fields must be private and preferably final
Ensure the class cannot be overridden - make the class final, or use static factories and keep constructors private
Fields must be populated from the Constructor/Factory
Don't provide any setters for the fields
Watch out for collections. Use Collections.unmodifiable*.
Also, collections should contain only immutable Objects
All the getters must provide immutable objects or use defensive copying
Don't provide any methods that change the internal state of the Object.
Now I have the following class..
public final class Bill {
private final int amount;
private final DateTime dateTime;
private final List<Integers> orders;
}
Please advise how it can be made as immutable class.
Your class as it is is immutable. Now you probably want to add a few methods:
public final class Bill {
private final int amount;
private final DateTime dateTime;
private final List<Integers> orders;
public Bill(int amount, DateTime dateTime, List<Integer> orders) {
this.amount = amount; //primitive type: ok
this.dateTime = dateTime; //joda.DateTime is immutable: ok
this.orders = new ArrayList<Integer> (orders); //make a copy as the caller could modify the list at its end
}
// no method that adds or removes from the list
public List<Integer> getOrders() {
return Collections.unmodifiableList(orders); //defensive copy
}
}
Alternatively, you can use this.orders = Collections.unmodifiableList(orders); in the constructor and return it from getOrders(): return orders;, which enforces the fact that you should not modify that list, even within your class.
Since int is a primitive and DataTime (from JodaTime, I guess) is immutable, the only thing you need to do is to ensure that you use immutable list:
public final class Bill {
...
public Bill(int amount, DateTime dateTime, List<Integer> orders) {
this.amount = amount;
this.dateTime = dateTime;
this.orders = Collections.unmodifiableList(orders);
}
...
}
Obviously, you also need a constructor to initialize final fields and some methods that would access that fields.
Since amount is a value type, datetime is unmodifiable, if you return a Collections.unmodifiable() version of your orders attribute in its getter, the class would become immutable.

Categories

Resources