Must all properties of an immutable object be final? - java

Must immutable objects have all properties be final?
I would say they don't. But I don't know whether I am right or not.

The main difference between an immutable object (all properties final) and an effectively immutable object (properties aren't final but can't be changed) is safe publication.
You can safely publish an immutable object in a multi threaded context without having to worry about adding synchronization, thanks to the guarantees provided by the Java Memory Model for final fields:
final fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads. This can provide safety guarantees against misuse of an immutable class by incorrect or malicious code. final fields must be used correctly to provide a guarantee of immutability.
As a side note, it also enables to enforce immutability (if you try to mutate those fields in a future version of your class because you have forgotten it should be immutable, it won't compile).
Clarifications
Making all the fields of an object final does not make it immutable - you also need to make sure that (i) its state can't change (for example, if the object contains a final List, no mutating operations (add, remove...) must be done after construction) and (ii) you don't let this escape during construction
An effectively immutable object is thread safe once it has been safely published
Example of unsafe publication:
class EffectivelyImmutable {
static EffectivelyImmutable unsafe;
private int i;
public EffectivelyImmutable (int i) { this.i = i; }
public int get() { return i; }
}
// in some thread
EffectivelyImmutable.unsafe = new EffectivelyImmutable(1);
//in some other thread
if (EffectivelyImmutable.unsafe != null
&& EffectivelyImmutable.unsafe.get() != 1)
System.out.println("What???");
This program could in theory print What???. If i were final, that would not be a legal outcome.

You can easily guarantee immutability by encapsulation alone, so it's not necessary:
// This is trivially immutable.
public class Foo {
private String bar;
public Foo(String bar) {
this.bar = bar;
}
public String getBar() {
return bar;
}
}
However, you also must guarantee it by encapsulation in some cases, so it's not sufficient:
public class Womble {
private final List<String> cabbages;
public Womble(List<String> cabbages) {
this.cabbages = cabbages;
}
public List<String> getCabbages() {
return cabbages;
}
}
// ...
Womble w = new Womble(...);
// This might count as mutation in your design. (Or it might not.)
w.getCabbages().add("cabbage");
It's not a bad idea to do so to catch some trivial errors, and to demonstrate your intent clearly, but "all fields are final" and "the class is immutable" are not equivalent statements.

Immutable = not changeable. So making properties final is a good idea. If not all properties of an object are protected from being changed I wouldn't say the object is immutable.
BUT an object is also immutable if it doesn't provide any setters for it's private properties.

Immutable objects MUST not be modified in any way after their creation. final of course helps to achieve that. You guarantee that they will not ever be changed. BUT what if you have an array inside your object that is final? Of course the reference is not changable, but the elements are. Look here at almost the same question I gave also:
Link

Simply declaring an object as final does not make it inherently immutable. Take for example this class:
import java.util.Date;
/**
* Planet is an immutable class, since there is no way to change
* its state after construction.
*/
public final class Planet {
public Planet (double aMass, String aName, Date aDateOfDiscovery) {
fMass = aMass;
fName = aName;
//make a private copy of aDateOfDiscovery
//this is the only way to keep the fDateOfDiscovery
//field private, and shields this class from any changes that
//the caller may make to the original aDateOfDiscovery object
fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
}
/**
* Returns a primitive value.
*
* The caller can do whatever they want with the return value, without
* affecting the internals of this class. Why? Because this is a primitive
* value. The caller sees its "own" double that simply has the
* same value as fMass.
*/
public double getMass() {
return fMass;
}
/**
* Returns an immutable object.
*
* The caller gets a direct reference to the internal field. But this is not
* dangerous, since String is immutable and cannot be changed.
*/
public String getName() {
return fName;
}
// /**
// * Returns a mutable object - likely bad style.
// *
// * The caller gets a direct reference to the internal field. This is usually dangerous,
// * since the Date object state can be changed both by this class and its caller.
// * That is, this class is no longer in complete control of fDate.
// */
// public Date getDateOfDiscovery() {
// return fDateOfDiscovery;
// }
/**
* Returns a mutable object - good style.
*
* Returns a defensive copy of the field.
* The caller of this method can do anything they want with the
* returned Date object, without affecting the internals of this
* class in any way. Why? Because they do not have a reference to
* fDate. Rather, they are playing with a second Date that initially has the
* same data as fDate.
*/
public Date getDateOfDiscovery() {
return new Date(fDateOfDiscovery.getTime());
}
// PRIVATE //
/**
* Final primitive data is always immutable.
*/
private final double fMass;
/**
* An immutable object field. (String objects never change state.)
*/
private final String fName;
/**
* A mutable object field. In this case, the state of this mutable field
* is to be changed only by this class. (In other cases, it makes perfect
* sense to allow the state of a field to be changed outside the native
* class; this is the case when a field acts as a "pointer" to an object
* created elsewhere.)
*/
private final Date fDateOfDiscovery;
}

No.
For example, see the implementation of java.lang.String. Strings are immutable in Java, but the field hash is not final (it is lazily computed the first time hashCode is called and then cached). But this works because hash can take on only one nondefault value that is the same every time it is computed.

String class is Immutable but property hash is not final
Well it is possible but with some rules/restrictions and that is access to mutable properties/fields must provide same result every time we access it.
In String class hashcode actually calculated on the final array of characters which is not going to change if String has constructed. Therefore immutable class can contain mutable fields/properties but it has to make sure that access to field/property will produce the same result every time it is accessed.
To answer your question it is not mandatory to have all the fields final in a immutable class.
For further reading visit here [blog] : http://javaunturnedtopics.blogspot.in/2016/07/string-is-immutable-and-property-hash.html

Not necessary, you can achieve same functionality by making member as non-final but private and not modifying them except in constructor. Don't provide setter method for them and if it is a mutable object, then don't ever leak any reference for that member.
Remember making a reference variable final, only ensures that it will not be reassigned a different value, but you can still change individual properties of an object, pointed by that reference variable. This is one of the key points.

Related

Enum backed by enum in Java [duplicate]

I'm developing a LALG compiler to my college course on Java 1.6. So I did a types class and grammar class.
EnumTypes
public enum EnumTypes {
A("OLA"),
B("MUNDO"),
C("HELLO"),
D("WORLD"),
/**
* The order below is reversed on purpose.
* Revert it and will you get a NULL list of types furder.
*/
I(EnumGrammar.THREE),
H(EnumGrammar.TWO),
F(EnumGrammar.ONE),
E(EnumGrammar.ZERO);
private String strValue;
private EnumGrammar enumGrammarValue;
private EnumTypes(String strValue) {
this.strValue = strValue;
}
private EnumTypes(EnumGrammar enumGrammarValue) {
this.enumGrammarValue = enumGrammarValue;
}
public String getStrValue() {
return strValue;
}
public EnumGrammar getEnumTiposValue() {
return enumGrammarValue;
}
}
EnumGrammar
public enum EnumGrammar {
ZERO(EnumTypes.A,EnumTypes.B,EnumTypes.F,EnumTypes.D),
ONE(EnumTypes.C),
TWO(EnumTypes.B,EnumTypes.H),
THREE(EnumTypes.D,EnumTypes.A,EnumTypes.C);
private EnumTypes[] values;
private EnumGrammar(EnumTypes ... values) {
this.values = values;
}
public EnumTypes[] getValues() {
return values;
}
}
When I call EnumTypes.E.getEnumTiposValue().getValues() where are supposed to be the EnumTypes.F value is NULL.
Main
public class Main {
public static void main(String[] args) {
//prints [A, B, null, D]
System.out.println(Arrays.toString(EnumTypes.E.getEnumTiposValue().getValues()));
}
}
There are a workaround or something like that?
Thanks!
Essentially, it is always a very risky thing to allow a reference to an object to get outside of the class before the class is fully constructed, that is before the constructor is finished. Enums are singletons. Here you have two classes whose constructors receive each other's instances in a circular dependency. Add to this that class loading is lazy, so the classes will be loaded and enum instances created as you go and it sounds quite reasonable that the ends result depends on the order in which the enums are initialized.
I can't quote the corresponding point from JLS right now (I'll look for it), but I believe that if you allow a reference to an object to "leave the class" from outside of the constructor (which happens here due to enums being singletons initialized by the JVM), the JVM is free to do something strange.
EDIT: these points from the JLS are of importance for the case:
17.5.2 - A read of a final field of an object within the thread that constructs that object is ordered with respect to the initialization of that field within the constructor by the usual happens-before rules. If the read occurs after the field is set in the constructor, it sees the value the final field is assigned, otherwise it sees the default value. Since enum values are internally treated like static final fields (see 16.5 below), if you reference one enum from inside the constructor of another enum whose constructor references the first one, at least one of these two objects will not yet have been fully initialized and so the reference may still be null at this point.
16.5 - The definite assignment/unassignment status of any construct within the class body of an enum constant is governed by the usual rules for classes
8.3.2 - rules for initialization of fields
12.4.1 - when initialization occurs
Here is what's happening, in order:
Your code calls EnumTypes.E.getEnumTiposValue(), triggering class loading of EnumTypes.
Static initialization of EnumTypes begins - its enum constants will be initialized in the order they're declared.
EnumTypes.A through EnumTypes.D are initialized.
EnumTypes.I begins initialization - its constructor call references EnumGrammar.THREE, triggering class loading of EnumGrammar.
Static initialization of EnumGrammar begins - its enum constants will be initialized in the order they're declared.
EnumGrammar.ZERO is initialized - its constructor call references EnumTypes.A, EnumTypes.B, EnumTypes.F, and EnumTypes.D. Out of those, EnumTypes.F has not yet been initialized. Therefore, the reference to it is null.
From there, static initialization of the two enum classes finishes, but it doesn't matter for EnumGrammar.ZERO - its values field has already been set.
For the workaround, suppose that you have EnumA and EnumB, I will just put EnumB's name in EnumA's constructor.
When you have to retrieve EnumB from EnumA, you can simply use EnumB.valueOf(EnumA.this.enumB)
For example, Question is the EnumB
public enum Question {
RICH_ENOUGH(R.string.question_rich_enough, Arrays.asList(Answer.RICH_ENOUGH_YES, Answer.RICH_ENOUGH_NO)),
ARE_YOU_SURE(R.string.question_are_you_sure, Arrays.asList(Answer.ARE_YOU_SURE_YES, Answer.ARE_YOU_SURE_NO)),
FOUND_A_NEW_JOB(R.string.question_found_new_job, Arrays.asList(Answer.FOUND_A_NEW_JOB_YES, Answer.FOUND_A_NEW_JOB_NO)),
// ...
and Answer is the EnumA
public enum Answer {
RICH_ENOUGH_YES(R.string.answer_yes, "ARE_YOU_SURE"),
RICH_ENOUGH_NO(R.string.answer_no, "THAT_SOMEBODY"),
ARE_YOU_SURE_YES(R.string.answer_yes, null),
ARE_YOU_SURE_NO(R.string.answer_no, "FOUND_A_NEW_JOB"),
FOUND_A_NEW_JOB_YES(R.string.answer_yes, "GO_FOR_NEW_JOB"),
// ...
private final int answerStringRes;
// Circular reference makes nulls
private final String nextQuestionName;
Answer(#StringRes int answerStringRes, String nexQuestionName) {
this.answerStringRes = answerStringRes;
this.nextQuestionName = nexQuestionName;
}
Whenever I need to get the next Question from an Answer
public Question getNextQuestion() {
if (nextQuestionName == null) {
return null;
}
return Question.valueOf(nextQuestionName);
}
This should be simple enough to be a workaround.
Example source: an open source Android app for fun I just written last night - Should I Resign?

Immutability - Java, Final required if no setters [duplicate]

Must immutable objects have all properties be final?
I would say they don't. But I don't know whether I am right or not.
The main difference between an immutable object (all properties final) and an effectively immutable object (properties aren't final but can't be changed) is safe publication.
You can safely publish an immutable object in a multi threaded context without having to worry about adding synchronization, thanks to the guarantees provided by the Java Memory Model for final fields:
final fields also allow programmers to implement thread-safe immutable objects without synchronization. A thread-safe immutable object is seen as immutable by all threads, even if a data race is used to pass references to the immutable object between threads. This can provide safety guarantees against misuse of an immutable class by incorrect or malicious code. final fields must be used correctly to provide a guarantee of immutability.
As a side note, it also enables to enforce immutability (if you try to mutate those fields in a future version of your class because you have forgotten it should be immutable, it won't compile).
Clarifications
Making all the fields of an object final does not make it immutable - you also need to make sure that (i) its state can't change (for example, if the object contains a final List, no mutating operations (add, remove...) must be done after construction) and (ii) you don't let this escape during construction
An effectively immutable object is thread safe once it has been safely published
Example of unsafe publication:
class EffectivelyImmutable {
static EffectivelyImmutable unsafe;
private int i;
public EffectivelyImmutable (int i) { this.i = i; }
public int get() { return i; }
}
// in some thread
EffectivelyImmutable.unsafe = new EffectivelyImmutable(1);
//in some other thread
if (EffectivelyImmutable.unsafe != null
&& EffectivelyImmutable.unsafe.get() != 1)
System.out.println("What???");
This program could in theory print What???. If i were final, that would not be a legal outcome.
You can easily guarantee immutability by encapsulation alone, so it's not necessary:
// This is trivially immutable.
public class Foo {
private String bar;
public Foo(String bar) {
this.bar = bar;
}
public String getBar() {
return bar;
}
}
However, you also must guarantee it by encapsulation in some cases, so it's not sufficient:
public class Womble {
private final List<String> cabbages;
public Womble(List<String> cabbages) {
this.cabbages = cabbages;
}
public List<String> getCabbages() {
return cabbages;
}
}
// ...
Womble w = new Womble(...);
// This might count as mutation in your design. (Or it might not.)
w.getCabbages().add("cabbage");
It's not a bad idea to do so to catch some trivial errors, and to demonstrate your intent clearly, but "all fields are final" and "the class is immutable" are not equivalent statements.
Immutable = not changeable. So making properties final is a good idea. If not all properties of an object are protected from being changed I wouldn't say the object is immutable.
BUT an object is also immutable if it doesn't provide any setters for it's private properties.
Immutable objects MUST not be modified in any way after their creation. final of course helps to achieve that. You guarantee that they will not ever be changed. BUT what if you have an array inside your object that is final? Of course the reference is not changable, but the elements are. Look here at almost the same question I gave also:
Link
Simply declaring an object as final does not make it inherently immutable. Take for example this class:
import java.util.Date;
/**
* Planet is an immutable class, since there is no way to change
* its state after construction.
*/
public final class Planet {
public Planet (double aMass, String aName, Date aDateOfDiscovery) {
fMass = aMass;
fName = aName;
//make a private copy of aDateOfDiscovery
//this is the only way to keep the fDateOfDiscovery
//field private, and shields this class from any changes that
//the caller may make to the original aDateOfDiscovery object
fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
}
/**
* Returns a primitive value.
*
* The caller can do whatever they want with the return value, without
* affecting the internals of this class. Why? Because this is a primitive
* value. The caller sees its "own" double that simply has the
* same value as fMass.
*/
public double getMass() {
return fMass;
}
/**
* Returns an immutable object.
*
* The caller gets a direct reference to the internal field. But this is not
* dangerous, since String is immutable and cannot be changed.
*/
public String getName() {
return fName;
}
// /**
// * Returns a mutable object - likely bad style.
// *
// * The caller gets a direct reference to the internal field. This is usually dangerous,
// * since the Date object state can be changed both by this class and its caller.
// * That is, this class is no longer in complete control of fDate.
// */
// public Date getDateOfDiscovery() {
// return fDateOfDiscovery;
// }
/**
* Returns a mutable object - good style.
*
* Returns a defensive copy of the field.
* The caller of this method can do anything they want with the
* returned Date object, without affecting the internals of this
* class in any way. Why? Because they do not have a reference to
* fDate. Rather, they are playing with a second Date that initially has the
* same data as fDate.
*/
public Date getDateOfDiscovery() {
return new Date(fDateOfDiscovery.getTime());
}
// PRIVATE //
/**
* Final primitive data is always immutable.
*/
private final double fMass;
/**
* An immutable object field. (String objects never change state.)
*/
private final String fName;
/**
* A mutable object field. In this case, the state of this mutable field
* is to be changed only by this class. (In other cases, it makes perfect
* sense to allow the state of a field to be changed outside the native
* class; this is the case when a field acts as a "pointer" to an object
* created elsewhere.)
*/
private final Date fDateOfDiscovery;
}
No.
For example, see the implementation of java.lang.String. Strings are immutable in Java, but the field hash is not final (it is lazily computed the first time hashCode is called and then cached). But this works because hash can take on only one nondefault value that is the same every time it is computed.
String class is Immutable but property hash is not final
Well it is possible but with some rules/restrictions and that is access to mutable properties/fields must provide same result every time we access it.
In String class hashcode actually calculated on the final array of characters which is not going to change if String has constructed. Therefore immutable class can contain mutable fields/properties but it has to make sure that access to field/property will produce the same result every time it is accessed.
To answer your question it is not mandatory to have all the fields final in a immutable class.
For further reading visit here [blog] : http://javaunturnedtopics.blogspot.in/2016/07/string-is-immutable-and-property-hash.html
Not necessary, you can achieve same functionality by making member as non-final but private and not modifying them except in constructor. Don't provide setter method for them and if it is a mutable object, then don't ever leak any reference for that member.
Remember making a reference variable final, only ensures that it will not be reassigned a different value, but you can still change individual properties of an object, pointed by that reference variable. This is one of the key points.

Usage of final in java

I was wondering what the difference is between
public final type attribute_name;
and
private type attribute_name;
public type getA_name() {
return attribute_name;
}
Basically I want to make an attribute read-only, so it can't change after it has been initialized.
Do I make it public final, or do I make it private, and only make it accesible through a get method (without a set method)?
When it's not final but private, the class itself is able to change the value.
A final field MUST be set before the constructor exits. Once set, the reference cannot be modified (the value cannot be reassigned). Emphasis on the cannot be reassigned. This means that while the reference cannot change, the value itself can change.
This is legal:
final List<Integer> list = new List<Integer>();
list.add(5); // the value of list changes, but the reference doesn't
This is not:
final List<Integer> list = new List<Integer>();
list = new List<Integer>(); // may seem sort of redundant but the compiler won't allow it nonetheless
A private variable with a only getter can be reassigned internally by the class that holds it (but it's not visible externally so it cannot be reassigned outside the class holding it). Also, outside the class the reference is inaccessible so the variable cannot be modified except by the class holding it.
A final variable cannot be reassigned anywhere, but if it's public, another class can still access the reference and change the value of whatever object it points to.
If you don't want the variable to be reassigned after initialization as you described, use both final and private.
Use final for something like this:
public class User {
private final long registrationTimeMillis;
public User(/* various parameters probably would be here */) {
registrationTimeMillis = System.currentTimeMillis();
}
public long getRegistrationTimeMillis() {
return registrationTimeMillis;
}
}
We don't expect that a user's registration time will change, so it makes sense to not allow it to change after construction.
Use private with no setter for something like this:
public class VendingController() {
private int drinksStocked = 0;
private int drinksDispensed = 0;
public void dispenseDrink() {
drinksDispensed++;
}
public void stockDrinks(int numberOfDrinks) {
drinksStocked = getDrinksRemaining() + numberOfDrinks;
drinksDispensed = 0;
}
public int getDrinksRemaining() {
return drinksStocked - drinksDispensed;
}
}
We don't want the value of drinksDispensed to change except when dispenseDrink() or stockDrinks(int numberOfDrinks) is called. It still needs to be able to be reassigned by it's own class when the vending machine is refilled though, so we shouldn't make it final
With respect to using public final, generally in Java that's only done for constants and that static keyword is also included since constants shouldn't be dependent on an instance.
An example of when it makes sense to use public static final
public class UnitConversions {
public static final double CENTIMETERS_PER_INCH = 2.54;
}
It could then be used in a method as follows
public double convertFromCentimetersToInches(double centimeters) {
return centimeters / UnitConversions.CENTIMETERS_PER_INCH;
}
Best of luck OP and happy coding.
More reading on final fields
This depends on some factors.
If this is a real constant that is known before and will never change, then use final. In Java final fields can be initialized in the constructor as well, so if your value is known at construction time then you can use final too.
If this value gets set (once, multiple times) during runtime then use private + getter.
The final modifier allows a field to be assigned only once - it cannot be changed after that and it has to be set at during object construction (that is, before the constructor returns).
If you want to make the field read-only, use the principles of information hiding: make it private and provide a public getter that returns the field (or a copy of it for non-primitive types).
You should use public final only for true constants. Even if your field is immutable because of final it is often a good idea to still make it private.
The correct way is to think in the future. What would help you achieve your goals? Maybe later you would also like to give that variable a value. If I were you, I'd do this by creatin a get method and keeping the variable private.
Full documentation for final keyword : http://en.wikipedia.org/wiki/Final_(Java)
Depends on where you want to access it from. Public variables can be accessed from any class within the project and package where private can only be accessed from the class where the variable is.
The 'final' operator makes it permanent and read-only.
Let's assume that type is a reference to an object, not a primitive type.
public final type attribute_name means that attribute_name cannot be reassigned to refer to something else. But attribute_name can be used to call a method that changes its state.
In private type attribute_name, only methods within the class can call methods on attribute_name.
So if you want it to remain constant, use approach (2). Limit the public methods to ones that ultimately call methods on attribute_name that don't modify its state.

Is there a method in java that returns member variables of a class

I have a requirement to check if the member variables of a class are there in a list or not. For this, I need to get all the variables of a class dynamically (if possible as a list). Is there a method for that in java?
Thanks,
KD
This is the concept of Reflection. You should be able to do something like the following (untested) code snippet:
/**
* #return {#code true} if all of the values of the fields in {#code obj} are
* contained in the set of {#code values}; {#code false} otherwise.
*/
public boolean containsAllValues(HashSet<Object> values, MyClass obj) {
Field[] fields = MyClass.class.getFields();
for (Field field : fields) {
Object fieldValue = field.get(obj);
if (values.contains(fieldValue)) {
return false;
}
}
return true;
}
You may get all of the field names (and their values) by calling Class#getFields()
Example: Consider the class below
public class Test{
public int x, y, z;
}
Test.class.getFields() will return the fields x,y,z, in which you could get their name through Field#getName() and get their value by calling the appropriate get method. In the Test class above, you could do something like this:
Test instance = new Test();
instance.x = 50;
int xValue = Test.class.getField("x").getInt(instance);
The value of xValue would be 50.
For a better demonstration of how it works, please see this.
You're talking about reflection.
Have a look at Class.getFields():
http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html
See also:
http://forgetfulprogrammer.wordpress.com/2011/06/13/java-reflection-class-getfields-and-class-getdeclaredfields/
There are quite a lot of fishhooks with reflection. Property-based access -- bean properties, of the form getX()/setX() or isX()/setX() -- may be a little better in helping you avoid unstable implementation internal of the class.
You can use the getFields() method, that will return a Field array: http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getFields()
And then the getName() method for each element in the Field[] to get the name: http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Field.html#getName().
Most answers recommend Class.getFields() but as the JavaDoc states, it will only return the public fields:
Returns an array containing Field objects reflecting all the
accessible public fields of the class or interface represented by this
Class object.
I rarely make my class fields public and rather make them private with getters and setters. To get the list of all fields (including private, protected and package private) you need to use Class.getDeclaredFields():
Returns an array of Field objects reflecting all the fields declared
by the class or interface represented by this Class object. This
includes public, protected, default (package) access, and private
fields, but excludes inherited fields.
Note that unlike Class.getFields(), Class.getDeclaredFields() will not returned the inherited fields. To get those you need to loop through the class hierarchy (loop over Class.getSuperclass() until you reach Object.class). Private fields names could be repeated in parent classes.

Make immutable Java object

My goal is to make a Java object immutable. I have a class Student. I coded it in the following way to achieve immutability:
public final class Student {
private String name;
private String age;
public Student(String name, String age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public String getAge() {
return age;
}
}
My question is, what is the best way to achieve immutability for the Student class?
Your class is not immutable strictly speaking, it is only effectively immutable. To make it immutable, you need to use final:
private final String name;
private final String age;
Although the difference might seem subtle, it can make a significant difference in a multi-threaded context. An immutable class is inherently thread-safe, an effectively immutable class is thread safe only if it is safely published.
There are few things that you must consider for making an immutable class:
Make your class final - You already have
Make all the fields private and final - Make appropriate changes in your code
Don't provide any methods that change the state of your instance
If you have mutable fields in your class, like List, or Date, making them final won't suffice. You should return a defensive copy from their getters, so that their state isn't mutated by calling methods.
For the 4th point, say you have a Date field in your class, then the getter for that field should look like:
public Date getDate() {
return new Date(this.date.getTime());
}
Making a defensive copy can become a headache, when your mutable field itself comprises of some mutable field, and that in turn can contain some other mutable field. In that case, you would need to make copy of each of them iteratively. We name this iterative copy of mutable fields as Deep Copy.
Implementing deep copy by yourself may be cumbersome. But,keeping that issue apart, you should consider your class design again, once you see yourself falling into such requirement of making deep defensive copy.
How do you make a mutable object immutable?
Declare the class as final so it can’t be extended.
Make all fields private so that direct access is not allowed.
Don’t provide setter methods for variables
Make all mutable fields final so that it’s value can be assigned only once.
Initialize all the fields via a constructor performing deep copy.
Perform cloning of objects in the getter methods to return a copy rather than returning the actual object reference.
source
Why do we create immutable objects?
Immutable objects are simply objects whose state (the object's data) cannot change after construction.
Security: store sensitive pieces of information like usernames, passwords, connection URLs, network connections etc.
are simple to construct, test, and use
are automatically thread-safe and have no synchronization issues
don't need a copy constructor
don't need an implementation of clone
allow hashCode to use lazy initialization, and to cache its return value
don't need to be copied defensively when used as a field
make good Map keys and Set elements (these objects must not change state while in the collection)
have their class invariant established once upon construction, and it never needs to be checked again
always have "failure atomicity" (a term used by Joshua Bloch): if an immutable object throws an exception, it's never left in an undesirable or indeterminate state
Source
In Java, Strings are immutable, which provides, such as caching, security, easy reuse without replication, etc.
Source
With final keyword:
private final String name;
private final String age;
Making variables private and no setter methods will work for primitive data types. If my class has any collection of objects?
To making any class immutable with collection object?
Write your own collection object with extends collection class and follow the private variables and no setter methods. or return clone object of your collection object.
public final class Student {
private StudentList names;//Which is extended from arraylist
public Student() {
names = DAO.getNamesList()//Which will return All Student names from Database its upto you how you want to implement.
}
public StudentList getStudentList(){
return names;//you need to implement your own methods in StudentList class to iterate your arraylist; or you can return Enumeration object.
}
public Enumeration getStudentNamesIterator(
Enumeration e = Collections.enumeration(names);
return e;
}
public class StudentList extends ArrayList {
}
This is fine but I would make the fields final as well.
Also I would make the age an int or double rather than a String.
Expanding on the answer a bit.
final is not the same as Immutable but you can use final to make certain things immutable if you use it in certain ways.
Certain types are immutable, in that they represent unchanging values rather than objects of changeable state. Strings, numbers, etc are immutable. At the end, usually our objects boil down to data structures eventually referencing immutable values, but we change the data structures by assigning new values to the same field names.
So to make something truly immutable you need to make sure that final is used all the way down, until you reach every field reaching every value at the base of your composition tree. Otherwise something could change out from under your the object and it isn't really fully immutable.
Your example is already immutable object, because fields in Student class can only set on instance initialization.
To make object immutable, You must do these steps:
Don't use any methods, which can change fields of your class. For example don't use Setters.
Avoid to use public non-final fields. If your fields is public then you must declare them as final and initialize them in constructor or directly in the declaration line.
It is too late to answer but may be it help other peoples who have this question.
State of immutable object can not be modified after construction, any modification should result in new immutable object.
All fields of Immutable class should be final.
Object must be properly constructed i.e. object reference must not leak during construction process.
Object should be final in order to restrict sub-class for altering immutability of parent class.
I think this link help more
Read more: http://javarevisited.blogspot.com/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html#ixzz40VDQDDL1
It already is immutable -- you can't change the contents once you initialize it, since you haven't made setters. You might add final keywords to the variables.
Making all variables as final and when setting some field, making it return the reference to the new Student object with the newly set value like in String.
You can just follow guidelines shown in this example (first result in google):
http://www.javapractices.com/topic/TopicAction.do?Id=29
Here are few rules, which helps to make a class immutable in Java :
1. State of immutable object can not be modified after construction, any modification should result in new immutable object.
2. All fields of Immutable class should be final.
3. Object must be properly constructed i.e. object reference must not leak during construction process.
4. Object should be final in order to restrict sub-class for altering immutability of parent class.
Example:
public final class Contacts {
private final String name;
private final String mobile;
public Contacts(String name, String mobile) {
this.name = name;
this.mobile = mobile;
}
public String getName(){
return name;
}
public String getMobile(){
return mobile;
}
}
Refer this link : http://javarevisited.blogspot.in/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html
According to Strategy for Defining Immutable Objects
Don't provide "setter" methods — methods that modify fields or
objects referred to by fields.
Make all fields final and private.
Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final.
a. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
If the instance fields include references to mutable objects, don't allow those objects to be changed:
a. Don't provide methods that modify the mutable objects.
b. Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.
Java SE 16
You can use JEP 395: Records feature, introduced as part of Java SE 16, to create an immutable class in a succinct manner.
If you have already gone through the above link, you must have figured out that you can do it simply as
record Student(String name, String age) { }
What you get in turn are:
A final class Student.
A canonical constructor whose signature is the same as the header, Student(String name, String age).
private final fields, name and age and their corresponding public accessor method with the same name and return type.
Automatically created equals, hashCode and toString methods.
Demo:
Student.java
record Student(String name, String age) { }
Main.java
class Main{
public static void main(String[] args) {
Student s1 = new Student("Bharat", "10 Years");
Student s2 = new Student("Arvind", "10 Years");
System.out.println(s1);
System.out.println(s1.equals(s2));
System.out.println(s1.age().equals(s2.age()));
}
}
Output:
Student[name=Bharat, age=10 Years]
false
true
Make the class or variable as final that's more than enough
Public final class constants
{
private final String name;
private final String mobile;
// code
}

Categories