
코드가 의도하지 않은 결과를 가져오는 것을 말한다.
객체 A의 상태를 변경하는 코드를 작성했는데, 이 코드가 객체 B의 상태도 변경시키는 경우, 이는 사이드이펙트이다.

primitive type / value type (원시 타입/값 타입)
boolean, byte, short, int, long, char, float, doublereference type (참조 타입)
// Student.class
public class Student {
private String name;
private String major;
public Student(String name, String major) {
this.name = name;
this.major = major;
}
public void setMajor(String major) {
this.major = major;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", major='" + major + '\'' +
'}';
}
}
// StudentMain.class
public class StudentMain {
public static void main(String[] args) {
Student studentA = new Student("코뉴", "Computer Science");
Student studentB = studentA;
System.out.println("studentA와 studentB는 \"코뉴\" 라는 이름을 가진 동명이인이고, 둘 다 컴퓨터과학 전공이다.");
System.out.println("studentA = " + studentA);
System.out.println("studentB = " + studentB);
System.out.println("\n어느날, studentB인 코뉴는 수학과로 전과한다.");
studentB.setMajor("Mathematics");
System.out.println("studentA = " + studentA);
System.out.println("studentB = " + studentB);
System.out.println("‼️studentA인 코뉴까지 전산에서 전공이 바뀌었다!");
}
}
// 출력 결과
studentA와 studentB는 "코뉴" 라는 이름을 가진 동명이인이고, 둘 다 컴퓨터과학 전공이다.
studentA = Student{name='코뉴', major='Computer Science'}
studentB = Student{name='코뉴', major='Computer Science'}
어느날, studentB인 코뉴는 수학과로 전과한다.
studentA = Student{name='코뉴', major='Mathematics'}
studentB = Student{name='코뉴', major='Mathematics'}
‼️studentA인 코뉴까지 전산에서 전공이 바뀌었다!
StudentA와 StudentB가 같은 객체를 가리키고 있었기 때문에 발생하는 문제이다.String, Integer, LocalDate 등이 불변 객체로 설계되어 있다.
final로 선언한다.//ImmutableStudent.class
public class ImmutableStudent {
private final String name;
private final String major;
public ImmutableStudent(String name, String major) {
this.name = name;
this.major = major;
}
public ImmutableStudent withMajor(String major) {
return new ImmutableStudent(name, major);
}
@Override
public String toString() {
return "ImmutableStudent{" +
"name='" + name + '\'' +
", major='" + major + '\'' +
'}';
}
}
// ImmutableStudentMain.class
public class ImmutableStudentMain {
public static void main(String[] args) {
ImmutableStudent studentA = new ImmutableStudent("코뉴", "ComputerScience");
ImmutableStudent studentB = studentA;
System.out.println("studentA와 studentB는 \"코뉴\" 라는 이름을 가진 동명이인이고, 둘 다 컴퓨터과학 전공이다.");
System.out.println("studentA = " + studentA);
System.out.println("studentB = " + studentB);
System.out.println("\n어느날, studentB인 코뉴는 수학과로 전과한다.");
studentB = studentB.withMajor("Mathematics");
System.out.println("studentA = " + studentA);
System.out.println("studentB = " + studentB);
}
}
// 출력 결과
studentA와 studentB는 "코뉴" 라는 이름을 가진 동명이인이고, 둘 다 컴퓨터과학 전공이다.
studentA = ImmutableStudent{name='코뉴', major='ComputerScience'}
studentB = ImmutableStudent{name='코뉴', major='ComputerScience'}
어느날, studentB인 코뉴는 수학과로 전과한다.
studentA = ImmutableStudent{name='코뉴', major='ComputerScience'}
studentB = ImmutableStudent{name='코뉴', major='Mathematics'}
name, major에 final 키워드를 사용해 값 수정을 불가능하게 했다.withMajor 메서드를 생성하여 major 값 변경이 필요한 경우, 새로운 객체를 리턴하도록 했다.