2013-12-25 2 views
8

Как создать неизменяемый класс в java. , если класс ученика имеет отношение (адрес), как создать неизменяемый класс. Я хочу сделать класс ниже неизменногоКак создать неизменяемый класс в java

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); 

     } 
     } 

Здесь мы можем modifiy экземпляры адреса. Пожалуйста, дайте мне идею

ответ

15

ключевых точки для неизменны не являются:

  • нет Сеттеры методы
  • делает переменные частные и конечные
  • возвратных списков с помощью Collections.unmodifiableList - никогда не возвращать какое-либо изменяемое поле; всегда возвращайте либо копию (если необходимо), либо неизменяемую версию поля
  • make class final
  • Если переменные изменяются внутри класса, это изменение не отображается и не имеет эффекта вне класса (в том числе затрагивает такие вещи, как equals() и hashcode()).
+0

все поля являются частными и окончательными. Нет метода setter. – user2832497

+1

. Определение класса адреса должно также соответствовать приведенным выше правилам. –

+0

Третья пуля должна быть обобщена на: «никогда не возвращать какое-либо изменяемое поле, всегда возвращайте либо копию (если необходимо, глубоко), либо неизменяемую версию поля». –

4

В классе Address вы должны сделать ваши поля private (должно) и final (сусло), как это -

public final class Address {  // so no sub-classes can be made. 
    private final int aid;   // private and final. 
    private final String street;  // private and final. 
    // as before. 
} 

Вы также не можете иметь методы установщиков, но когда поля являются окончательными, что является не большая проблема (поскольку любой метод setter даст ошибку компилятора).

+0

все поля приватные и окончательные нет метода setter private final Адрес add – user2832497

2

Ну вы сделали студент полу-неизменны хорошо:

  • Его атрибуты являются окончательными
  • они неизменных типов (кроме адреса)
  • и они инициализируются в конструкторе.

Вы должны применить то же самое Address класса, поэтому он стал непреложным, а потом все состояние Student будет неизменен. Так что это будет:

public final class Address { 
    private final int aid; 
    private final String street; 

    public Address(int aid, String street) { 
     this.aid = aid; 
     this.street = street; 
    } 


    public int getAid() { 
     return aid; 
    } 

    public String getStreet() { 
     return street; 
    } 

    .... 
} 

К счастью, у вас нет никаких изменяемых типов (некоторые из наиболее хорошо knowns являются Date, Collection s и Maps), в противном случае вы должны рассмотреть их.

Если у вас есть какие-либо изменчивые атрибуты, вы должны скопировать его в конструктор, и вы должны вернуть немодифицируемую копию или копию ее там, где существует утечка.

Например, если ваш Student класс имел атрибут birthDate, вы должны сделать что-то вроде:

public final class Student { 
    private final Date birthDate; 

    public Student(int sid, String name, Address address, Date birthDate) { 
     this.sid = sid; 
     this.name = name; 
     this.address = address; 
     this.birthDate = (birthDate == null) ? null : new Date(birthDate.getTime()); 
    } 

    public Date getBirthDate() { 
     return (birthDate == null) ? null : new Date(birthDate.getTime()); 
    } 

    .... 

} 
+0

public Student (int sid, String name, Address add) { super(); this.sid = sid; this.name = name; this.add = add; } // Адрес инициализирован в конструкторе – user2832497

+0

Хорошо, я упомянул, что он должен сделать «Адрес» неизменным на первом месте. –

+0

Я хочу, чтобы класс адреса неизменен, нет. Класс даты. Пожалуйста, не указывайте чистый soln. – user2832497

0

этого достаточно. Объявленный final не может быть мутирован, и поскольку в конструкторе в качестве аргументов необходимы аргументы, то getter являются избыточными.

final public class Student { 

    public final Address add; 
    public final int sid; 
    public final String name; 

    public Student(int sid, String name, Address add) { 
     super(); 
     this.sid = sid; 
     this.name = name; 
     this.add = add; 
    } 

    @Override 
    public String toString() { 
     return "Student [add=" + add + ", name=" + name + ", sid=" + sid + "]"; 
    } 
} 

address и studentId/id бы лучше имена полей, хотя.

Смежные вопросы