Classı kənar müdaxilələrdən qorumağın digər üsulu isə həmin classı immutable etməkdir. Classı immutable etmək üçün birinci addım setter metodları ləğv etməkdir. Bu zaman sual yarana bilər ki, bəs əgər classı çağıran adamın (caller) spesifik dəyər təyin etməyi hələ də bacarmasını istəsək nə etməliyik? Bu zaman parametrli constructorlar köməyimizə gəlir.
class ImmutableCourse { private int countStudents; public ImmutableCourse(int countStudents) { this.countStudents = countStudents; } public int getCountStudents() { return countStudents; } }
Burada setter
metodun gördüyü işi constructor görür. Obyekt yaradıldıqdan sonra (after instantiation) isə dəyərlərin dəyişdirilməsi mümkün deyil. Amma mutable obyektlərlə diqqətli davranmaq lazımdı. Aşağıdakı nümunə ilə bunun səbəbini əsaslandırmağa çalışaq:
public class NotImmutable { private StringBuilder builder; public NotImmutable(StringBuilder b) { builder = b; } public StringBuilder getBuilder() { return builder; } } class TestNotImmutable { public static void main(String[] args) { StringBuilder sb = new StringBuilder("kitab"); NotImmutable n = new NotImmutable(sb); sb.append(" bilik"); StringBuilder builder = n.getBuilder(); builder.append(" menbeyidir"); System.out.println(n.getBuilder()); // kitab bilik menbeyidir } }
Gördüyünüz kimi biz ancaq “kitab”
sözünü göndərdik, amma sonda nəticə dəyişdi və bu biz istəyən nəticə deyil! Problem ondadır ki, biz builder
dəyişəninə yaratdığımız StringBuilder
obyektinin referansını mənimsədirik və bununla da bu dəyişənlərin hər ikisi eyni StringBuilder
obyektinə işarə edir, birini dəyişdikdə digəri də dəyişir. Yaxud getBuilder()
metodundan builder
referansının özünü geri döndürürük və bu referans vasitəsilə yenə də obyekti dəyişmək mümkündür. Həll yolu isə odur ki, biz bu obyektlərin kopyasını yaratmalıyıq:
class Immutable { private StringBuilder builder; public Immutable(StringBuilder b) { builder = new StringBuilder(b); } public StringBuilder getBuilder() { return new StringBuilder(builder); } }
Və yaxud da metodun geri dönüş tipini String
olaraq dəyişmək olar:
public String getValue(){ return builder.toString(); }
[topics lang=az]