OCA Java imtahan mövzuları

Final Initialization

Final dəyişənlər elan olunarkən onlara mütləq dəyər mənimsədilməlidir və bu ancaq bir dəfə baş verə bilər, final dəyişənlərə 2-ci dəfə dəyər mənimsətmək mümkün deyil. Final staticfinal instance dəyişənlər üçün dəyər mənimsədilməsi bir az fərqlidir, baxaq.

  • final static dəyişənlərə dəyər mənimsədilə bilər:
  1. elan olunduğu sətirdə;
  2. static initializer blokda.
  • final instance dəyişənlərə dəyər mənimsədilə bilər:
  1. elan olunduğu sətirdə;
  2. instance initializer blokda;
  3. constructor`da.

Constructor tamamlananda bütün final instance dəyişənlərin hamısına mütləq dəyər mənimsədilməlidir. Əgər qeyd olunan halların heç birində dəyər mənimsədilməsə compile xətası baş verəcək.

Local final dəyişənlərə dəyər mənimsədilməsi ilə bağlı isə mütləq məcburiyyət yoxdur. Local dəyişənlər üçün standart qayda var: istifadə olunmadan öncə mütləq initialize olunmalıdır. Local final dəyişənlər də sadəcə bu qaydaya riayət etməlidir, əgər istifadə olunacaqsa, dəyər mənimsədilməlidir, əks halda compile xətası vermir.

public class Finals {

  // static final variables - sf
  private static final int sf1;          // DOES NOT COMPILE
  private static final int sf2 = 10;
  private static final int sf3;
  private static int s4;
  static {
      System.out.println(s4);    // 0
      sf3 = 100;
  }

  // instance final variables - if
  private final int if1;   // DOES NOT COMPILE, bunun xətasını əslində constructorda göstərir
  private final int if2 = 20;
  private final int if3;
  private final int if4;
  private int i5;

  {
    if4 = 200;
    if2 = 21;       // DOES NOT COMPILE
  }

  public Finals() {
    System.out.println(i5);      // 0
    if3 = 200;
  }

  public void method() {
    // local final variables
    final int a1;
    final int a2;
    final int a3;   // unused
    int b1;
    int b2;
    int b3;         // unused
    System.out.println(a1);      // DOES NOT COMPILE
    System.out.println(b1);      // DOES NOT COMPILE
    a2 = 30;
    System.out.println(a2);
    b2 = 3;
    System.out.println(b2);
    b2 = 300;
    System.out.println(b2);
    a2 = 15;                   // DOES NOT COMPILE
  }    
}

Ətraflı bu linkdən baxa bilərsiniz:

http://www.coderanch.com/t/640116/ocajp/certification/Final-instance-variable-initialization-behaviour#2937716

 

İndi maraqlı bir kod nümunəsinə baxacağıq, yuxarıda qeyd edilən qaydalar ödənilmir, amma buna baxmayaraq compile xətası vermir:

class FinalKeywordExample {
    final boolean bool;  // line1
    static { System.out.println("static initializer"); }
    {  System.out.println("instance initializer"); }

    FinalKeywordExample() {
        throw new RuntimeException();   // line2
    }

    public static void main(String[] args) {
        FinalKeywordExample i = new FinalKeywordExample();
        System.out.println(i.bool);
    }
}

Koddan da gördüyünüz kimi line1-də final bool dəyişəni yaradılıb və nə elan olunduğu sətirdə, nə instance initializer blokda, nə də constructor`da ona dəyər mənimsədilməyib. Amma buna baxmayaraq compile xətası vermir. Xəta verməməsinin səbəbi isə line2-də RuntimeException fırladılmasıdır. Əgər line2-ni kommentə salsaq, o zaman line1 compile xətası verəcək və bool dəyişəninə dəyər mənimsədilməsi tələb ediləcək.

Aşağıdakı nümunə sizi çaşdıra bilər. listarray referans dəyişənlərdir, yəni biz listə yeni dəyər əlavə etdikdə, yaxud massivin müvafiq indeksindəki dəyərini başqa dəyərlə əvəz etdikdə, bu final dəyişənə təkrar dəyər mənimsədilməsi hesab olunmur. Referans dəyişənə yeni obyekt mənimsətdikdə artıq compile xətası baş verir:

private static final ArrayList<String> list = new ArrayList<>();
private static final int array[] = {1, 2};
public static void main(String[] args) {
    list.add("changed");
    array[1] = 3;
    list = new ArrayList<>();      // DOES NOT COMPILE
    array = new int[]{4, 5};       // DOES NOT COMPILE    
}

 

Aşağıdakı nümunə də maraqlı nümunədir, bənzər print ifadəsi main metodda xəta verir, amma increaseX metodunda xəta vermir:

public static void main(String[] args) {
    final int x = 15;
    increaseX(x);
    System.out.println(++x);  // DOES NOT COMPILE
}

public static void increaseX(int x){
    System.out.println(++x);  // prints 16
}

Səbəb Java`nın “pass by value” özəlliyinə görədir, yəni x dəyişəni main metodda final dəyişən olsa da, increaseX metodunda final dəyişən deyil. “pass by value” mövzusu ilə növbəti məqalədə tanış olacağıq.

 

[topics lang=az]

About the author

Mushfiq Mammadov

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.

 

This site uses Akismet to reduce spam. Learn how your comment data is processed.