Неабходнасць ініцыялізацыі канчатковага заданні ў межах спараметрированного канструктара (ов) у Java

import java.util.*;

public Class C
{
     final Vector v;
     C()
     {
          v=new Vector();
     }

     C(int i)
     {
          //Here, it is an error. v might not have been initialized.
     }

     public void someMethod()
     {
           System.out.println(v.isEmpty());
     }

     public static void main(String[] args)
     {
          C c=new C();
          c.someMethod();
     }
} 

Вышэй код кампіляцыі памылка часу. Я ведаю, але ён кажа (у NetBeans) пераменная v павінна быць ініцыялізаваны. Калі я ініцыялізуюцца яго ў перагружаным канструктару ён выпраўляе гэтую праблему і друкуе «ісціну». Мая праблема ў тым, чаму я павінен ініцыялізаваць яго зноў у перагружанай версіі канструктараў. (Я ініцыялізуецца яго адзін раз у канструктару па змаўчанні), і я нават не выкарыстоўваючы перагружанай версію. Чаму?

0
Адным з магчымых варыянтаў з'яўляецца змяненне яго канчатковы вектар v = новы вектар (); . Тады вам не прыйдзецца пісаць яго ў канструктарах.
дададзена аўтар Vlad, крыніца
Тое ж самае ставіцца, калі вы робіце гэта праз канструктар (ов). Калі вам трэба перадаць яго, або калі вы не хочаце, каб ініцыялізаваць вектар на будаўніцтва, то ён не можа быць канчатковым.
дададзена аўтар Vlad, крыніца
Гэта таксама правільна, Улад, але гэта не дазволіць v быць ініцыялізаваны пазней, як гэта канчатковы член, калі ў гэтым узнікне неабходнасць.
дададзена аўтар Bhavesh, крыніца
Так, я зразумеў сваю памылку, Улад. Вялікі дзякуй.
дададзена аўтар Bhavesh, крыніца

3 адказы

Паколькі перагружаны канструктар ня выклікаецца па змаўчанні.

Выкарыстоўвайце гэта() , каб выклікаць яго.

5
дададзена
+1 - А таксама той факт, што v аб'яўляецца канчатковым. Калі б не было канчатковым, то гэта не было б нармальна (без памылак кампіляцыі).
дададзена аўтар CoolBeans, крыніца

Пры стварэнні новага аб'екта, толькі адзін з канструктараў вашага класа выклікаецца для ініцыялізацыі аб'екта. Вы, здаецца, думаюць, што ўсё канструктары называюцца, або па змаўчанні (не-аргументы) Канструктар заўсёды выклікаецца. Гэта не так.

Такім чынам, кожны канструктар павінен ініцыялізаваць усе зменныя канчатковы членаў.

Звярніце ўвагу, што з аднаго канструктара можна відавочна выклікаць іншы, выкарыстоўваючы гэта (...) . Напрыклад, у першым радку вашага C (ідэалам я) канструктар, можна дадаць радок: гэта (); для выкліку C() канструктар. Іншым рашэннем з'яўляецца для ініцыялізацыі зменнай-члена ў радку, дзе вы аб'яўляеце яго:

public class C {
   //v will be initialized, no matter which constructor will be used
    final Vector v = new Vector();

    C() {
    }

    C(int i) {
       //...
    }

   //... etc.
}

Звярніце ўвагу, што вам не трэба відавочна ініцыялізаваць не- канчатковыя зменныя-члены; калі вы не ініцыялізаваць тых, Java будзе ініцыялізаваць іх значэнне па змаўчанні (які нулявы для зменных непримитивного тыпу). Тым не менш, вы павінны відавочна ініцыялізаваць зменныя канчатковы членаў.

Яшчэ адна заўвага: Vector гэта клас спадчыну калекцыі. Вы павінны аддаць перавагу выкарыстоўваць ArrayList замест гэтага.

Third note: Use generics to make your code more type-safe. For example, if you need to store strings in a list, use ArrayList instead of the raw type ArrayList.

4
дададзена

Перагружаны канструктар ня выклікаецца іншы варыянт, калі вы відавочна не зрабіць гэта з

this();

Гэта, верагодна, тое, што вы хочаце зрабіць.

1
дададзена