Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create immutable class in java

Tags:

java

How can create immutable class in java. if Student class has a relationship(address) how to create immutable class. I want to make the class below immutable

  final public class Student {
        private final Address add;
            private final int sid;
            public Student(int sid, String name, Address add) {
                super();
                this.sid = sid;
                this.name = name;
                this.add = add;
            }
            private final String name;
            public int getSid() {
                return sid;
            }
            public final String getName() {
                return name;
            }
            @Override
            public String toString() {
                return "Student [add=" + add + ", name=" + name + ", sid=" + sid + "]";
            }
            public Address getAdd() {
                return add;
            }


        }

        //I want to make the class below immutable
        public class Address {
            public int getAid() {
                return aid;
            }
            public String getStreet() {
                return street;
            }
            @Override
            public String toString() {
                return "Address [aid=" + aid + ", street=" + street + "]";
            }
            int aid;
            String street;
            public Address(int aid, String street) {
                super();
                this.aid = aid;
                this.street = street;
            }

        }


        public class First {
        public static void main(String[] args) {
            Address myAdd=new Address(179,"Maihill");
            Student st=new Student(99,"anoj",myAdd);
            System.out.println(st.toString());
            myAdd.aid=2376;
            System.out.println(st);
            System.out.println("***************");
            Address pAdd=st.getAdd();
            //Here modified address instance then how we can make immutable.
                pAdd.aid=788;
            System.out.println(st);

        }
        }

Here we can modifiy address instances. Please give me idea

like image 316
user2832497 Avatar asked Dec 25 '13 04:12

user2832497


People also ask

Why do we create immutable class in Java?

Immutable objects are thread-safe so you will not have any synchronization issues. Immutable objects are good Map keys and Set elements, since these typically do not change once created. Immutability makes it easier to parallelize your program as there are no conflicts among objects.

What are all the immutable classes in Java?

In Java, all the wrapper classes like Boolean, Short, Integer, Long, Float, Double, Byte, Char, and String classes are immutable classes.


2 Answers

The key points for immutable are:

  • no setters methods
  • make variables private and final
  • return lists using Collections.unmodifiableList - never return any mutable field; always return either a copy (deep if appropriate) or an immutable version of the field
  • make class final
  • if variables are changed internally in the class this change is not visible and has no effect outside of the class (including affecting things like equals() and hashcode()).
like image 181
Scary Wombat Avatar answered Oct 10 '22 03:10

Scary Wombat


record

As of Java 16, we can use the records feature (also previewed in Java 14, and previewed in Java 15). Using record is the simplest, hassle-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 printRectanglesIntersect(Rectangle rectangleA, Rectangle rectangleB) {
    System.out.println("Checking Rectangle intersection..");
  }
}
like image 28
Player_Neo Avatar answered Oct 10 '22 04:10

Player_Neo