Recently on the interview I had an interesting question.
We have mutable class:
final class Example {
private int i;
private String s;
private Object o;
// get, set
}
And instance of this class Example e = new Example();
Can we somehow make this instance immutable? Without changing original class.
My thoughts:
Deep cloning of this instance? But not sure if it's possible.
Maybe something like serialization/deserialization?
If you are unable to make modifications to the Example class and you cannot subclass it (in your snippet, it is marked as final) the closest solution I can think of is to create a wrapper class, which is immutable. This is not a perfect solution, and has it's drawbacks.
First, how to do it:
final class ImmutableExample {
// Redeclare every field as in the Example class
// but make sure they can't be reassigned
// (in this case I'll declare them as final)
private final int i;
private final String s;
private final Object o;
ImmutableExample(Example mutableExample) {
// copy fields from original
this.i = mutableExample.getI();
this.s = mutableExample.getS();
this.o = mutableExample.getO();
}
// add getters but definitely no setters
}
Then everywhere you have code like this:
Example e = new Example();
e.setI(42); // etc
Change to:
Example e = new Example();
e.setI(42); // etc
ImmutableExample immutableE = new ImmutableExample(e);
And pass around references to immutableE, and make sure that the e reference does not escape.
Now, for the drawbacks:
ImmutableExample is not an instance of Example, so you cannot pass the immutable type to a method which expects the mutable type, and operations like if (immutableE instanceof Example) or (Example)immutableE will not work as before
You have to be very careful that every field of Example is also immutable, or ImmutableExample will also be mutable. Consider, for example, that the field of type Object could be something mutable, like a HashMap or a Date.
When the Example class changes, you have to repeat the change in ImmutableExample.
If it was possible to subclass Example, or if it was an interface, this approach might be more useful, but I can't see any other way when Example cannot be subclassed.
If each of those fields have getters/setters, then to make it immutable, you will have to
Make each field private and final
Make a copy of each field when it's getter is called
Remove all setters
Any methods within the class that changes it's state must either be removed or use the new getters to access any internals
Immutability is a property of a class not an instance. So besides bytecode twiddling or other means to change the class; not possible.
With a none final class i would create an immutable decorator. That would not make the instance immutable, but provide an immutable wrapper to that instance.
You could not assign the instance to any variable/field, making it impossible to change it ;)
Related
I have the following class:
package com.tesco.demandforecasting.group8.choprachap7;
import java.util.ArrayList;
import com.tesco.demandforecasting.group8.utils.MathOperUtils;
import com.tesco.demandforecasting.group8.utils.RegressionUtils;
import lombok.Getter;
/**
* This class if used to find seasonality factor of each period, as explain in
* the chapter See https://kelley.iu.edu/mabert/e730/Chopra-Chap-7.pdf for the
* explanation
*/
#Getter
public class ChopraChap7SeasonalFactorsCalculator {
private double[] regressionParams;
private int sales_size;
private int periodicity;
private ArrayList<Integer> sales;
private ArrayList<Double> deseasonalisedData;
private ArrayList<Double> deseasonalisedDemandUsingRegression;
private ArrayList<Double> seasonalityFactors;
public ChopraChap7SeasonalFactorsCalculator() {
this.sales = new ArrayList<>();
this.deseasonalisedData = new ArrayList<>();
this.deseasonalisedDemandUsingRegression = new ArrayList<>();
this.seasonalityFactors = new ArrayList<>();
this.sales.add(8000);
this.sales.add(13000);
this.sales.add(23000);
this.sales.add(34000);
this.sales.add(10000);
this.sales.add(18000);
this.sales.add(23000);
this.sales.add(38000);
this.sales.add(12000);
this.sales.add(13000);
this.sales.add(32000);
this.sales.add(41000);
this.sales_size = sales.size();
this.periodicity = 4;
calculateSeasonalityFactors();
}
private void calculateSeasonalityFactors() {
.......
.......
this.seasonalityFactors = seasonalityFactors;
this.deseasonalisedDemandUsingRegression = deseasonalisedDemandUsingRegression;
this.deseasonalisedData = deseasonalisedData;
}
}
I want to expose the class fields to external classes, using their respective getters. But, the problem is that those fields attain any value only after the ChopraChap7SeasonalFactorsCalculator() method is called. So, what I have done here is call the method as soon as an object of the class is created. Of course, this will work, but is this good design pattern?
Supposing I would not have called the method from the constructor. So, if we have the following code is some other class:
ChopraChap7SeasonalFactorsCalculator calc = new ChopraChap7SeasonalFactorsCalculator();
calc.getDeseasonalisedData();
This will return to me any empty array list. How do I ensure that the method is called before any field is accessed?
What would be the best design pattern in my case?
Of course, this will work, but is this good design pattern?
This is a very correct design. You delegate a part of the constructor logic into a private method to make things clearer.
This will return to me any empty array list. How do I ensure that the
method is called before any field is accessed?
Your fear about someone changes something in the constructor may be true for any methods or chunks of code.
But applications are not designed to check that each component does what we expect from it. This is the unit tests role to assert that the actual behavior is which one expected.
So write an unit test for the ChopraChap7SeasonalFactorsCalculator constructor and in this test assert that all getters return the expected values once the object is created.
If someone modifies the constructor in an incorrect way, the test will fail and the build too. You have your way to make sure things are as expected now.
I think that's pretty fine. The constructor is there to create a useful object. If you are sure the object cannot be used without these being set there is no reason why not to set them in the constructor.
If you check https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html
A class contains constructors that are invoked to create objects from
the class blueprint.
You have added the fields but you don't have a working object without these being set and apparently you know the values already. The best way to do it would be leave these in the constructor. If there are some unknown values or requirements in order to create an instance of that class you can consider Factory pattern or something but in your case constructor usage is just fine.
How to create immutable objects in Java?
Which objects should be called immutable?
If I have class with all static members is it immutable?
Below are the hard requirements of an immutable object.
Make the class final
make all members final, set them
explicitly, in a static block, or in the constructor
Make all members private
No Methods that modify state
Be extremely careful to limit access to mutable members(remember the field may be final but the object can still be mutable. ie private final Date imStillMutable). You should make defensive copies in these cases.
The reasoning behind making the class final is very subtle and often overlooked. If its not final people can freely extend your class, override public or protected behavior, add mutable properties, then supply their subclass as a substitute. By declaring the class final you can ensure this won't happen.
To see the problem in action consider the example below:
public class MyApp{
/**
* #param args
*/
public static void main(String[] args){
System.out.println("Hello World!");
OhNoMutable mutable = new OhNoMutable(1, 2);
ImSoImmutable immutable = mutable;
/*
* Ahhhh Prints out 3 just like I always wanted
* and I can rely on this super immutable class
* never changing. So its thread safe and perfect
*/
System.out.println(immutable.add());
/* Some sneak programmer changes a mutable field on the subclass */
mutable.field3=4;
/*
* Ahhh let me just print my immutable
* reference again because I can trust it
* so much.
*
*/
System.out.println(immutable.add());
/* Why is this buggy piece of crap printing 7 and not 3
It couldn't have changed its IMMUTABLE!!!!
*/
}
}
/* This class adheres to all the principles of
* good immutable classes. All the members are private final
* the add() method doesn't modify any state. This class is
* just a thing of beauty. Its only missing one thing
* I didn't declare the class final. Let the chaos ensue
*/
public class ImSoImmutable{
private final int field1;
private final int field2;
public ImSoImmutable(int field1, int field2){
this.field1 = field1;
this.field2 = field2;
}
public int add(){
return field1+field2;
}
}
/*
This class is the problem. The problem is the
overridden method add(). Because it uses a mutable
member it means that I can't guarantee that all instances
of ImSoImmutable are actually immutable.
*/
public class OhNoMutable extends ImSoImmutable{
public int field3 = 0;
public OhNoMutable(int field1, int field2){
super(field1, field2);
}
public int add(){
return super.add()+field3;
}
}
In practice it is very common to encounter the above problem in Dependency Injection environments. You are not explicitly instantiating things and the super class reference you are given may actually be a subclass.
The take away is that to make hard guarantees about immutability you have to mark the class as final. This is covered in depth in Joshua Bloch's Effective Java and referenced explicitly in the specification for the Java memory model.
Just don't add public mutator (setter) methods to the class.
Classes are not immutable, objects are.
Immutable means: my public visible state cannot change after initialization.
Fields do not have to be declared final, though it can help tremendously to ensure thread safety
If you class has only static members, then objects of this class are immutable, because you cannot change the state of that object ( you probably cannot create it either :) )
To make a class immutable in Java , you can keep note of the following points :
1. Do not provide setter methods to modify values of any of the instance variables of the class.
2. Declare the class as 'final' . This would prevent any other class from extending it and hence from overriding any method from it which could modify instance variable values.
3. Declare the instance variables as private and final.
4. You can also declare the constructor of the class as private and add a factory method to create an instance of the class when required.
These points should help!!
From oracle site, how to create immutable objects in Java.
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 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:
I. Don't provide methods that modify the mutable objects.
II. 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.
An immutable object is an object that will not change its internal state after creation. They are very useful in multithreaded applications because they can be shared between threads without synchronization.
To create an immutable object you need to follow some simple rules:
1. Don't add any setter method
If you are building an immutable object its internal state will never change. Task of a setter method is to change the internal value of a field, so you can't add it.
2. Declare all fields final and private
A private field is not visible from outside the class so no manual changes can't be applied to it.
Declaring a field final will guarantee that if it references a primitive value the value will never change if it references an object the reference can't be changed. This is not enough to ensure that an object with only private final fields is not mutable.
3. If a field is a mutable object create defensive copies of it for
getter methods
We have seen before that defining a field final and private is not enough because it is possible to change its internal state. To solve this problem we need to create a defensive copy of that field and return that field every time it is requested.
4. If a mutable object passed to the constructor must be assigned to a
field create a defensive copy of it
The same problem happens if you hold a reference passed to the constructor because it is possible to change it. So holding a reference to an object passed to the constructor can create mutable objects. To solve this problem it is necessary to create a defensive copy of the parameter if they are mutable objects.
Note that if a field is a reference to an immutable object is not necessary to create defensive copies of it in the constructor and in the getter methods it is enough to define the field as final and private.
5. Don't allow subclasses to override methods
If a subclass override a method it can return the original value of a mutable field instead of a defensive copy of it.
To solve this problem it is possible to do one of the following:
Declare the immutable class as final so it can't be extended
Declare all methods of the immutable class final so they can't be overriden
Create a private constructor and a factory to create instances of the immutable class because a class with private constructors can't be extended
If you follow those simple rules you can freely share your immutable objects between threads because they are thread safe!
Below are few notable points:
Immutable objects do indeed make life simpler in many cases. They are especially applicable for value types, where objects don't have an identity so they can be easily replaced and they can make concurrent programming way safer and cleaner (most of the notoriously hard to find concurrency bugs are ultimately caused by mutable state shared between threads).
However, for large and/or complex objects, creating a new copy of the object for every single change can be very costly and/or tedious. And for objects with a distinct identity, changing an existing objects is much more simple and intuitive than creating a new, modified copy of it.
There are some things you simply can't do with immutable objects, like have bidirectional relationships. Once you set an association value on one object, it's identity changes. So, you set the new value on the other object and it changes as well. The problem is the first object's reference is no longer valid, because a new instance has been created to represent the object with the reference. Continuing this would just result in infinite regressions.
To implement a binary search tree, you have to return a new tree every time: Your new tree will have had to make a copy of each node that has been modified (the un-modified branches are shared). For your insert function this isn't too bad, but for me, things got fairly inefficient quickly when I started to work on delete and re-balance.
Hibernate and JPA essentially dictate that your system uses mutable objects, because the whole premise of them is that they detect and save changes to your data objects.
Depending on the language a compiler can make a bunch of optimizations when dealing with immutable data because it knows the data will never change. All sorts of stuff is skipped over, which gives you tremendous performance benefits.
If you look at other known JVM languages (Scala, Clojure), mutable objects are seen rarely in the code and that's why people start using them in scenarios where single threading is not enough.
There's no right or wrong, it just depends what you prefer. It just depends on your preference, and on what you want to achieve (and being able to easily use both approaches without alienating die-hard fans of one side or another is a holy grail some languages are seeking after).
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 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:
Don't provide methods that modify the mutable objects.
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.
First of all, you know why you need to create immutable object, and what are the advantages of immutable object.
Advantages of an Immutable object
Concurrency and multithreading
It automatically Thread-safe so synchronization issue....etc
Don't need to copy constructor
Don't need to implementation of clone.
Class cannot be override
Make the field as a private and final
Force callers to construct an object completely in a single step, instead of using a no-Argument constructor
Immutable objects are simply objects whose state means object's data can't change after the
immutable object are constructed.
please see the below code.
public final class ImmutableReminder{
private final Date remindingDate;
public ImmutableReminder (Date remindingDate) {
if(remindingDate.getTime() < System.currentTimeMillis()){
throw new IllegalArgumentException("Can not set reminder" +
" for past time: " + remindingDate);
}
this.remindingDate = new Date(remindingDate.getTime());
}
public Date getRemindingDate() {
return (Date) remindingDate.clone();
}
}
Minimize mutability
An immutable class is simply a class whose instances cannot be modified. All of the information contained in each instance is provided when it is created and is fixed for the lifetime of the object.
JDK immutable classes: String, the boxed primitive classes(wrapper classes), BigInteger and BigDecimal etc.
How to make a class immutable?
Don’t provide any methods that modify the object’s state (known as mutators).
Ensure that the class can’t be extended.
Make all fields final.
Make all fields private.
This prevents clients from obtaining access to mutable objects referred to by fields and modifying these objects directly.
Make defensive copies.
Ensure exclusive access to any mutable components.
public List getList() {
return Collections.unmodifiableList(list); <=== defensive copy of the mutable
field before returning it to caller
}
If your class has any fields that refer to mutable objects, ensure that clients of the class cannot obtain references to these objects. Never initialize such a field to a client-provided object reference or return the object reference from an accessor.
import java.util.Date;
public final class ImmutableClass {
public ImmutableClass(int id, String name, Date doj) {
this.id = id;
this.name = name;
this.doj = doj;
}
private final int id;
private final String name;
private final Date doj;
public int getId() {
return id;
}
public String getName() {
return name;
}
/**
* Date class is mutable so we need a little care here.
* We should not return the reference of original instance variable.
* Instead a new Date object, with content copied to it, should be returned.
* */
public Date getDoj() {
return new Date(doj.getTime()); // For mutable fields
}
}
import java.util.Date;
public class TestImmutable {
public static void main(String[] args) {
String name = "raj";
int id = 1;
Date doj = new Date();
ImmutableClass class1 = new ImmutableClass(id, name, doj);
ImmutableClass class2 = new ImmutableClass(id, name, doj);
// every time will get a new reference for same object. Modification in reference will not affect the immutability because it is temporary reference.
Date date = class1.getDoj();
date.setTime(date.getTime()+122435);
System.out.println(class1.getDoj()==class2.getDoj());
}
}
For more information, see my blog:
http://javaexplorer03.blogspot.in/2015/07/minimize-mutability.html
an object is called immutable if its state can not be changed once created. One of the most simple way of creating immutable class in Java is by setting all of it’s fields are final.If you need to write immutable class which includes mutable classes like "java.util.Date". In order to preserve immutability in such cases, its advised to return copy of original object,
Immutable Objects are those objects whose state can not be changed once they are created, for example the String class is an immutable class. Immutable objects can not be modified so they are also thread safe in concurrent execution.
Features of immutable classes:
simple to construct
automatically thread safe
good candidate for Map keys and Set as their internal state would not change while processing
don't need implementation of clone as they always represent same state
Keys to write immutable class:
make sure class can not be overridden
make all member variable private & final
do not give their setter methods
object reference should not be leaked during construction phase
The following few steps must be considered, when you want any class as an immutable class.
Class should be marked as final
All fields must be private and final
Replace setters with constructor(for assigning a value to a
variable).
Lets have a glance what we have typed above:
//ImmutableClass
package younus.attari;
public final class ImmutableExample {
private final String name;
private final String address;
public ImmutableExample(String name,String address){
this.name=name;
this.address=address;
}
public String getName() {
return name;
}
public String getAddress() {
return address;
}
}
//MainClass from where an ImmutableClass will be called
package younus.attari;
public class MainClass {
public static void main(String[] args) {
ImmutableExample example=new ImmutableExample("Muhammed", "Hyderabad");
System.out.println(example.getName());
}
}
Commonly ignored but important properties on immutable objects
Adding over to the answer provided by #nsfyn55, the following aspects also need to be considered for object immutability, which are of prime importance
Consider the following classes:
public final class ImmutableClass {
private final MutableClass mc;
public ImmutableClass(MutableClass mc) {
this.mc = mc;
}
public MutableClass getMutClass() {
return this.mc;
}
}
public class MutableClass {
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
public class MutabilityCheck {
public static void main(String[] args) {
MutableClass mc = new MutableClass();
mc.setName("Foo");
ImmutableClass iMC = new ImmutableClass(mc);
System.out.println(iMC.getMutClass().getName());
mc.setName("Bar");
System.out.println(iMC.getMutClass().getName());
}
}
Following will be the output from MutabilityCheck :
Foo
Bar
It is important to note that,
Constructing mutable objects on an immutable object ( through the constructor ), either by 'copying' or 'cloing' to instance variables of the immutable described by the following changes:
public final class ImmutableClass {
private final MutableClass mc;
public ImmutableClass(MutableClass mc) {
this.mc = new MutableClass(mc);
}
public MutableClass getMutClass() {
return this.mc;
}
}
public class MutableClass {
private String name;
public MutableClass() {
}
//copy constructor
public MutableClass(MutableClass mc) {
this.name = mc.getName();
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
}
still does not ensure complete immutability since the following is still valid from the class MutabilityCheck:
iMC.getMutClass().setName("Blaa");
However, running MutabilityCheck with the changes made in 1. will result in the output being:
Foo
Foo
In order to achieve complete immutability on an object, all its dependent objects must also be immutable
From JDK 14+ which has JEP 359, we can use "records". It is the simplest and hustle free way of creating Immutable class.
A record class is a shallowly immutable, transparent carrier for a fixed set of fields known as the record components that provides a state description for the record. Each component gives rise to a final field that holds the provided value and an accessor method to retrieve the value. The field name and the accessor name match the name of the component.
Let consider the example of creating an immutable rectangle
record Rectangle(double length, double width) {}
No need to declare any constructor, no need to implement equals & hashCode methods. Just any Records need a name and a state description.
var rectangle = new Rectangle(7.1, 8.9);
System.out.print(rectangle.length()); // prints 7.1
If you want to validate the value during object creation, we have to explicitly declare the constructor.
public Rectangle {
if (length <= 0.0) {
throw new IllegalArgumentException();
}
}
The record's body may declare static methods, static fields, static initializers, constructors, instance methods, and nested types.
Instance Methods
record Rectangle(double length, double width) {
public double area() {
return this.length * this.width;
}
}
static fields, methods
Since state should be part of the components we cannot add instance fields to records. But, we can add static fields and methods:
record Rectangle(double length, double width) {
static double aStaticField;
static void aStaticMethod() {
System.out.println("Hello Static");
}
}
If an object reference is passed to a method, is it possible to make the object "Read Only" to the method?
Not strictly speaking. That is, a reference that can mutate an object can not be turned into a reference that can not mutate an object. Also, there is not way to express that a type is immutable or mutable, other than using conventions.
The only feature that ensure some form of immutability would be final fields - once written they can not be modified.
That said, there are ways to design classes so that unwanted mutation are prevented. Here are some techniques:
Defensive Copying. Pass a copy of the object, so that if it is mutated it doesn't break your internal invariants.
Use access modifiers and/or interface to expose only read-only methods. You can use access modifieres (public/private/protected), possibly combined with interface, so that only certain methods are visible to the other object. If the methods that are exposed are read-only by nature, you are safe.
Make your object immutable by default. Any operation on the object returns actually a copy of the object.
Also, note that the API in the SDK have sometimes methods that return an immutable version of an object, e.g. Collections.unmodifiableList. An attempt to mutate an immutable list will throw an exception. This does not enforce immutability statically (at compile-time with the static type system), but is is a cheap and effective way to enforce it dynamically (at run-time).
There has been many research proposals of Java extension to better control of aliasing, and accessibility. For instance, addition of a readonly keyword. None of them is as far as I know planned for inclusion in future version of Java. You can have a look at these pointers if you're interested:
Why We Should Not Add ''Read-Only'' to Java (yet) -- it lists and compare most of the proposals
The Checker Framework: Custom pluggable types for Java -- a non intrusive way to extend the type system, notably with immutable types.
The Checker Framework is very interesting. In the Checker Framework, look at Generic Universe Types checker, IGJ immutability checker, and Javari immutability checker. The framework works using annotations, so it is not intrusive.
No, not without decorating, compositing, cloning, etc.
There's no general mechanism for that. You'll need to write special-case code to achieve it, like writing an immutable wrapper (see Collections.unmodifiableList).
You could achieve a similar thing in most cases by cloning the Object as the first statement of the method, such as this...
public void readOnlyMethod(Object test){
test = test.clone();
// other code here
}
So if you called readOnlyMethod() and pass in any Object, a clone of the Object will be taken. The clone uses the same name as the parameter of the method, so there's no risk of accidentally changing the original Object.
No. But you could try to clone the object before passing it, so any changes made by the method won't affect the original object.
making it implement a interface which has only read only methods (no setter methods) this gives a copy of an object (road-only copy) and returning the read only instance of interface instead of returning the instance of an object itself
You could define all parameters of the objects as final but that makes the object read only to everyone.
I believe your real question is about avoiding escape references.
As pointed out in some answers to extract an Interface from class and expose only get methods. It will prevent modification by accident but it is again not a foolproof solution to avoid above problem.
Consider below example:
Customer.java:
public class Customer implements CustomerReadOnly {
private String name;
private ArrayList<String> list;
public Customer(String name) {
this.name=name;
this.list = new ArrayList<>();
this.list.add("First");
this.list.add("Second");
}
#Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public ArrayList<String> getList() {
return list;
}
public void setList(ArrayList<String> list) {
this.list = list;
}
}
CustomerReadOnly.java:
public interface CustomerReadOnly {
String getName();
ArrayList<String> getList();
}
Main.java:
public class Test {
public static void main(String[] args) {
CustomerReadOnly c1 = new Customer("John");
System.out.println("printing list of class before modification");
for(String s : c1.getList()) {
System.out.println(s);
}
ArrayList<String> list = c1.getList();
list.set(0, "Not first");
System.out.println("printing list created here");
for(String s : list) {
System.out.println(s);
}
System.out.println("printing list of class after modification");
for(String s : c1.getList()) {
System.out.println(s);
}
}
}
Ouput:
printing list of class before modification
First
Second
printing list created here
Not first
Second
printing list of class after modification
Not first
Second
So, as you can see extracting interface and exposing only get methods works only if you don't have any mutable member variable.
If you have a collection as a member variable whose reference you don't want to get escape from class, you can use Collections.unmodifiableList() as pointed out in ewernli's answer.
With this no external code can modify the underlying collection and your data is fully read only.
But again when it comes to custom objects for doing the same, I am aware of the Interface method only as well which can prevent modification by accident but not sure about the foolproof way to avoid reference escape.
Depending on where you want the rule enforced. If you are working collaboratively on a project, use final with a comment telling the next person they are not meant to modify this value. Otherwise wouldn't you simply write the method to not touch the object?
public static void main(String[] args) {
cantTouchThis("Cant touch this");
}
/**
*
* #param value - break it down
*/
public static void cantTouchThis(final String value) {
System.out.println("Value: " + value);
value = "Nah nah nah nah"; //Compile time error
}
So specifically to this method, the value will never be written to, and it is enforced at compile time making the solution extremely robust. Outside the scope of this method, the object remains unaltered without having to create any sort of wrapper.
private boolean isExecuteWriteQueue = false;
public boolean isWriting(){
final boolean b = isExecuteWriteQueue;
return b;
}
Expanding on ewernli's answer...
If you own the classes, you can use read-only interfaces so that methods using a read-only reference of the object can only get read-only copies of the children; while the main class returns the writable versions.
example
public interface ReadOnlyA {
public ReadOnlyA getA();
}
public class A implements ReadOnlyA {
#Override
public A getA() {
return this;
}
public static void main(String[] cheese) {
ReadOnlyA test= new A();
ReadOnlyA b1 = test.getA();
A b2 = test.getA(); //compile error
}
}
If you don't own the classes, you could extend the class, overriding the setters to throw an error or no-op, and use separate setters. This would effectively make the base class reference the read-only one, however this can easily lead to confusion and hard to understand bugs, so make sure it is well documented.
I have the following, stripped-down Java code:
// Class, in it's own file
import java.util.*;
public class Superclass {
protected List<Subclass> instances = new ArrayList<>();
public class Subclass extends Superclass {
private int someField;
public Subclass(int someValue) {
this.someField = someValue;
updateSuperclass();
}
private void updateSuperclass() {
super.instances.add(this);
}
}
}
// Implementation, somewhere else, everything has been imported properly
Superclass big = new Superclass();
Subclass little1 = big.new Subclass(1);
Subclass little2 = big.new Subclass(2);
Subclass little3 = big.new Subclass(3);
I want to implement a method in Superclass to do something with all the Subclasses. When a Subclass is created, it should add itself to a list in Superclass, but whenever I try to loop through that list in Superclass, it says the size is 1. The first element in the list (instances.get(0)) just spits out a String with all the proper information, but not in object form, and not separately. It's like every time I go to add to the list, it gets appended to the first (or zeroeth) element in String form.
How can I solve this so I can maintain an ArrayList of Subclasses to later loop over and run methods from? I'm definitely a beginner at Java, which doesn't help my case.
If all you need is a count then I suggest a static value that is updated in the constructor of the parent class.
private static int instanceCount = 0;
public Constructor() {
instanceCount++;
}
If you absolutely need every instance in a list so you can do something with them then I recommend you strongly re-consider your design.
You can always create a utility class that will let you maintain the list of objects to run processes on. It's more "Object Oriented" that way. You can also create one class that has all of the operations and then a simpler bean class that has only the data values.
But, if you insist, you can still use the same technique.
private static List<SuperClass> list = new LinkedList<SuperClass>;
public Constructor() {
list.add(this)
}
Each instance gets its own copy of your superclass's variables.
What you want to do is make the variable "static" by putting the static keyword before it. You probably don't even need the superclass accomplish what you're trying to do.
My question is regarding declaring an arraylist as final. I know that once I write final ArrayList list = new ArrayList(); I can add, delete objects from this list, but I can not list = new ArrayList() or list = list1. But what will be the use of declaring arraylist as
Private static final ArrayList list = new ArrayList();. And apart from the difference I have mentioned above what will be the difference between following two declaration:
1. ArrayList list = new ArrayList()
2. private static final ArrayList list = new ArrayList();
Just to "bring a little water to your Mill" you will understand the interest of final when you'll want to make your list publically availiable but unmodifiable.
In java one can make a list unmodifiable with Collections.unmodifiableList(modifiableList).
Now have a look to the following code :
public class MyClass{
public static List<String> MY_PUBLIC_LIST;
static{
ArrayList<String> tmp = new ArrayList<String>();
tmp.add("a");
tmp.add("b");
tmp.add("c");
MY_PUBLIC_LIST = tmp;
}
}
Well, in anyclass, anywhere in your code you can do something like this
MyClass.MY_PUBLIC_LIST = null;
MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");
When you add the final keyword to your variable, the first two won't be allowed
public static final List<String> MY_PUBLIC_LIST;
But you'll still be able to modify the content of the list :
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");
By adding a Collections.unmodifiableList(modifiableList) at the end of the static block you'll prevent this too :
MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);
Ok we are almost there. Just to be sure you get the whole picture lets keep the Collections.unmodifiableList(modifiableList) but let me remove the final modifier
public class MyClass{
public static List<String> MY_PUBLIC_LIST;
static{
ArrayList<String> tmp = new ArrayList<String>();
tmp.add("a");
tmp.add("b");
tmp.add("c");
MY_PUBLIC_LIST = Collections.unmodifiableList(tmp);
}
}
What can you do in that case ?
...
...
Well you can do whatever you want like in the first case (given that you assign the new list first) :
MyClass.MY_PUBLIC_LIST = null;
MyClass.MY_PUBLIC_LIST = new ArrayList<String>();
MyClass.MY_PUBLIC_LIST.clear();
MyClass.MY_PUBLIC_LIST.add("1");
You're right that declaring the list final means that you cannot reassign the list variable to another object.
The other question (I think) was
public class SomeClass {
private static final ArrayList list = new ArrayList();
}
vs
public class SomeClass {
ArrayList list = new ArrayList();
}
let's take each modifier in turn.
private Means only this class (SomeClass) can access list
static Means that there is only one instance of the list variable for all instances of SomeClass to share. The list instance is associated with the SomeClass class rather than each new SomeClass instance. If a variable is non-static it's said to be an instance variable
final as you know means that you cannot reassign the list variable another value.
In the second declaration there are no modifiers, so the variable is an instance variable and it also gets package-private access protection (Sometimes called default access protection). This means that this class (SomeClass) and other classes in the same package can access the variable.
You can find out more about public, private, and package-private here: Access control
You can find out more about final and static here: Class variables
When you say
final ArrayList list = new ArrayList();
this means that the variable list will always point to the same ArrayList object. There are two situations in which this can be useful.
You want to make sure that no-one reassigns your list variable once it has received its value. This can reduce complexity and helps in understanding the semantics of your class/method. In this case you are usually better off by using good naming conventions and reducing method length (the class/method is already too complex to be easily understood).
When using inner classes you need to declare variables as final in an enclosing scope so that you can access them in the inner class. This way, Java can copy your final variable into the inner class object (it will never change its value) and the inner class object does not need to worry what happens to the outer class object while the inner class object is alive and needs to access the value of that variable.
The second part of your question is about the difference between
ArrayList list = new ArrayList();
and
private static final ArrayList list = new ArrayList();
The difference of course are the modifiers. private means not visible outside the class, static means that it is defined on the class level and doesn't need an instance to exist, and final is discussed above. No modifiers means package-private or default access.
You say "I can add, delete (and find) objects", but who is I?
The different between your two cases concerns from which code those list operations can be called.
In general you need to consider the scope of the declaration, you greatly increase the maintainability of code if you reduce the visibility of your variables. If you have a class:
Public Class MyThing {
public int importantValue;
// more code
}
That important value can be changed by any other code, anywhere else in an application. If instead you make it private and provide a read accessor:
Public Class MyThing {
private int importantValue;
public int getImportantValue(){
return importantValue;
}
// more code
}
you now know only the class itself can change the value - for large applications this massively increases maintainability. So declaring the list private limits what code can see, and change the contents of the list.
The use of static makes the list shared by all instances of the class, rather than each instance getting its ovn copy.