JavaRush /Blog Jawa /Random-JV /Kesalahan programer java pemula. Bagean 2
articles
tingkat

Kesalahan programer java pemula. Bagean 2

Diterbitake ing grup
Kesalahan programer java pemula. Bagean 1

9. Nelpon cara kelas non-statis saka cara utama ().

Titik entri program Jawa apa wae kudu dadi cara statis main:
Kesalahan programer java pemula.  Bagean 2 - 1
public static void main(String[] args) {
  ...
}
Wiwit cara iki statis, sampeyan ora bisa nelpon cara kelas non-statis saka iku. Siswa asring lali babagan iki lan nyoba nelpon metode tanpa nggawe conto kelas. Kesalahan iki biasane digawe ing awal latihan, nalika siswa nulis program cilik. Tuladha sing salah:
public class DivTest {
    boolean divisible(int x, int y) {
        return (x % y == 0);
    }

    public static void main(String[] args) {
        int v1 = 14;
        int v2 = 9;

        // на следующие строки компилятор выдаст ошибку
        if (divisible(v1, v2)) {
            System.out.println(v1 + " is a multiple of " + v2);
        } else {
            System.out.println(v2 + " does not divide " + v1);
        }
    }
}
Ana 2 cara kanggo ndandani kesalahan: nggawe cara sing dikarepake statis utawa nggawe conto kelas. Kanggo milih cara sing bener, takon dhewe apa metode kasebut nggunakake lapangan utawa metode kelas liyane. Yen ya, sampeyan kudu nggawe conto kelas lan nelpon metode kasebut, yen ora, sampeyan kudu nggawe metode statis. Tuladha 1 sing dibenerake:
public class DivTest {
    int modulus;

    public DivTest(int m) {
      modulus = m;
    }

    boolean divisible(int x) {
        return (x % modulus == 0);
    }

    public static void main(String[] args) {
        int v1 = 14;
        int v2 = 9;

        DivTest tester = new DivTest(v2);

        if (tester.divisible(v1) {
            System.out.println(v1 + " is a multiple of " + v2);
        } else {
            System.out.println(v2 + " does not divide " + v1);
        }
    }
}
Tuladha 2 sing dibenerake:
public class DivTest {
    static boolean divisible(int x, int y) {
        return (x % y == 0);
    }

    public static void main(String[] args) {
        int v1 = 14;
        int v2 = 9;

        if (divisible(v1, v2)) {
            System.out.println(v1 + " is a multiple of " + v2);
        } else {
            System.out.println(v2 + " does not divide " + v1);
        }
    }
}

10. Nggunakake obyek kelas String minangka paramèter metode.

Ing Jawa, kelas java.lang.Stringnyimpen data string. Nanging, strings ing Jawa
  1. duwe permanen (yaiku, ora bisa diganti),
  2. yaiku obyek.
Mulane, dheweke ora bisa dianggep mung minangka buffer karakter; iku obyek sing ora bisa diganti. Kadhangkala siswa ngliwati senar ing pangarepan sing salah yen obyek senar bakal dilewati minangka array karakter kanthi referensi (kaya ing C utawa C ++). Compiler biasane ora nganggep iki minangka kesalahan. Conto sing salah.
public static void main(String args[]) {
   String test1 = "Today is ";
   appendTodaysDate(test1);
   System.out.println(test1);
}

/* прим. редактора: закомментированный метод должен иметь модификатор
    static (здесь автором допущена ошибка №9)
public void appendTodaysDate(String line) {
    line = line + (new Date()).toString();
}
*/

public static void appendTodaysDate(String line) {
    line = line + (new Date()).toString();
}
Ing conto ing ndhuwur, siswa pengin ngganti nilai variabel lokal test1kanthi menehi nilai anyar menyang parameter lineing metode appendTodaysDate. Alamiah iki ora bakal bisa. Tegese linebakal owah, nanging maknane test1bakal tetep padha. Kesalahan iki kedadeyan amarga salah pangerten yen (1) obyek java tansah dilewati dening referensi lan (2) strings ing java ora bisa diganti. Sampeyan kudu ngerti manawa obyek senar ora bakal ngganti regane, lan kabeh operasi ing senar nggawe obyek anyar. Kanggo ndandani kesalahan ing conto ing ndhuwur, sampeyan kudu salah siji bali senar saka cara, utawa pass obyek StringBufferminangka parameter kanggo cara tinimbang String. Tuladha 1 sing dibenerake:
public static void main(String args[]) {
   String test1 = "Today is ";
   test1 = appendTodaysDate(test1);
   System.out.println(test1);
}

public static String appendTodaysDate(String line) {
    return (line + (new Date()).toString());
}
Tuladha 2 sing dibenerake:
public static void main(String args[]) {
   StringBuffer test1 = new StringBuffer("Today is ");
   appendTodaysDate(test1);
   System.out.println(test1.toString());
}

public static void appendTodaysDate(StringBuffer line) {
    line.append((new Date()).toString());
}

kira-kira. ngartekne
Bener, ora gampang ngerti apa kesalahane. Wiwit obyek dilewati kanthi referensi, tegese linenuduhake panggonan sing padha karo test1. Iki tegese kanthi nggawe sing anyar line, kita nggawe sing anyar test1. Ing conto sing salah, kabeh katon kaya transfer Stringkasebut kanthi nilai, lan dudu referensi.

11. Nyatakake konstruktor minangka cara

Konstruktor obyek ing Jawa katon padha karo cara biasa. Bentenipun mung sing konstruktor ora nemtokake jinis bali lan jeneng padha jeneng kelas. Sayange, Jawa ngidini jeneng metode padha karo jeneng kelas. Ing conto ing ngisor iki, siswa pengin miwiti lapangan kelas Vector listnalika nggawe kelas. Iki ora bakal kedadeyan amarga metode 'IntList'dudu konstruktor. Conto sing salah.
public class IntList {
    Vector list;

    // Выглядит How конструктор, но на самом деле это метод
    public void IntList() {
        list = new Vector();
    }

    public append(int n) {
        list.addElement(new Integer(n));
    }
}
Kode bakal mbuwang pangecualian NullPointerExceptionnalika pisanan lapangan diakses list. Kesalahan gampang didandani: sampeyan mung kudu mbusak nilai bali saka header metode. Tuladha sing dibenerake:
public class IntList {
    Vector list;

    // Это конструктор
    public IntList() {
        list = new Vector();
    }

    public append(int n) {
        list.addElement(new Integer(n));
    }
}

12. Kelalen ngirim obyek menyang jinis sing dibutuhake

Kaya kabeh basa berorientasi obyek liyane, ing Jawa sampeyan bisa nyebut obyek minangka superclass. Iki diarani 'upcasting', rampung kanthi otomatis ing Jawa. Nanging, yen variabel, kolom kelas, utawa nilai bali metode diumumake minangka superclass, kolom lan metode subclass bakal ora katon. Referring superclass minangka subclass diarani 'downcasting', sampeyan kudu ndhaftar dhewe (yaiku, nggawa obyek menyang subclass sing dikarepake). Siswa asring lali babagan subclassing obyek. Iki paling kerep kedadeyan nalika nggunakake array Obyek lan koleksi saka paket java.util(tegese Framework Koleksi ). Conto ing ngisor iki Stringnglebokake obyek menyang array lan banjur mbusak saka array kanggo mbandhingake karo senar liyane. Compiler bakal ndeteksi kesalahan lan ora bakal ngumpulake kode nganti jinis cast wis tegas kasebut. Conto sing salah.
Object arr[] = new Object[10];
arr[0] = "m";
arr[1] = new Character('m');

String arg = args[0];
if (arr[0].compareTo(arg) < 0) {
    System.out.println(arg + " comes before " + arr[0]);
}
Tegese jinis casting angel kanggo sawetara. Cara dinamis utamane asring nyebabake kesulitan. Ing conto ing ndhuwur, yen cara wis digunakake equalstinimbang compareTo, compiler ora bakal di buwang kesalahan, lan kode wis bisa bener, wiwit cara equalssaka kelas bakal disebut String. Sampeyan kudu ngerti manawa panyambungan dinamis beda karo downcasting. Tuladha sing dibenerake:
Object arr[] = new Object[10];
arr[0] = "m";
arr[1] = new Character('m');

String arg = args[0];
if ( ((String) arr[0]).compareTo(arg) < 0) {
    System.out.println(arg + " comes before " + arr[0]);
}

13. Nggunakake antarmuka.

Kanggo akeh siswa, prabédan antarane kelas lan antarmuka ora jelas. Mula, sawetara siswa nyoba ngleksanakake antarmuka kayata Observerutawa Runnablenggunakake tembung kunci ngluwihi tinimbang ngleksanakake . Kanggo mbenerake kesalahan, sampeyan mung kudu mbenerake tembung kunci sing bener. Tuladha sing salah:
public class SharkSim extends Runnable {
    float length;
    ...
}
Tuladha sing dibenerake:
public class SharkSim implements Runnable {
    float length;
    ...
}
Kesalahan sing gegandhengan: Urutan ekstensi lan ngleksanakake blok sing salah . Miturut spesifikasi Jawa, deklarasi ekstensi kelas kudu teka sadurunge deklarasi implementasi antarmuka. Uga, kanggo antarmuka, tembung kunci implementasine kudu ditulis mung sapisan; sawetara antarmuka dipisahake karo koma. Sawetara conto liyane sing salah:
// Неправильный порядок
public class SharkSim implements Swimmer extends Animal {
    float length;
    ...
}

// ключевое слово implements встречается несколько раз
public class DiverSim implements Swimmer implements Runnable {
    int airLeft;
    ...
}
Tuladha sing dibenerake:
// Правильный порядок
public class SharkSim extends Animal implements Swimmer {
    float length;
    ...
}

// Несколько интерфейсов разделяются запятыми
public class DiverSim implements Swimmer, Runnable {
    int airLeft;
    ...
}

14. Kelalen nggunakake nilai bali saka cara superclass

Jawa ngidini sampeyan nelpon cara superclass sing padha saka subclass nggunakake tembung kunci tembung kunci. Kadhangkala siswa kudu nelpon metode superclass, nanging asring lali nggunakake nilai bali. Iki kedadeyan utamane ing antarane siswa sing durung ngerti metode lan nilai bali. Ing conto ing ngisor iki, siswa pengin nglebokake asil toString()metode superclass menyang asil toString()metode subclass. Nanging, ora nggunakake nilai bali saka cara superclass. Tuladha sing salah:
public class GraphicalRectangle extends Rectangle {
      Color fillColor;
      boolean beveled;
      ...
      public String toString() {
          super();
          return("color=" + fillColor + ", beveled=" + beveled);
      }
}
Kanggo mbenerake kesalahan, biasane cukup kanggo nemtokake nilai bali menyang variabel lokal, banjur gunakake variabel kasebut nalika ngetung asil metode subkelas. Tuladha sing dibenerake:
public class GraphicalRectangle extends Rectangle {
      Color fillColor;
      boolean beveled;
      ...
      public String toString() {
          String rectStr = super();
          return(rectStr + " - " +
         "color=" + fillColor + ", beveled=" + beveled);
      }
}

15. Kelalen nambah komponen AWT

AWT nggunakake model desain GUI prasaja: saben komponèn antarmuka kudu pisanan digawe nggunakake konstruktor dhewe, lan banjur diselehake menyang jendhela aplikasi nggunakake add()cara komponen induk. Mangkono, antarmuka ing AWT nampa struktur hirarkis. Siswa kadang lali 2 langkah kasebut. Dheweke nggawe komponen nanging lali nyelehake ing jendela pembesaran. Iki ora bakal nyebabake kesalahan ing tahap kompilasi; komponen kasebut ora bakal katon ing jendela aplikasi. Conto sing salah.
public class TestFrame extends Frame implements ActionListener {
    public Button exit;

    public TestFrame() {
        super("Test Frame");
        exit = new Button("Quit");
    }
}
Kanggo ndandani kesalahan iki, sampeyan mung kudu nambah komponen kanggo tuwane. Conto ing ngisor iki nuduhake carane nindakake iki. Perlu dicathet yen asring siswa sing lali nambah komponen menyang jendela aplikasi uga lali nemtokake pamireng acara menyang komponen kasebut. Tuladha sing dibenerake:
public class TestFrame extends Frame implements ActionListener {
    public Button exit;

    public TestFrame() {
        super("Test Frame");

        exit = new Button("Quit");

        Panel controlPanel = new Panel();
        controlPanel.add(exit);

        add("Center", controlPanel);

        exit.addActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        System.exit(0);
    }
}

17. Kelalen miwiti stream

Multithreading ing Jawa diimplementasikake nggunakake java.lang.Thread. Siklus urip thread kasusun saka 4 tahap: diinisialisasi, diwiwiti, diblokir lan mandheg. Utas sing mentas digawe ana ing negara wiwitan. Kanggo sijine menyang negara mlaku, sampeyan kudu nelpon sawijining start(). Kadhangkala siswa nggawe utas nanging lali miwiti. Biasane kesalahan kedadeyan nalika siswa ora duwe kawruh babagan program paralel lan multithreading. (approx. transl.: Aku ora weruh sambungan) Kanggo ndandani kesalahan, sampeyan mung kudu miwiti thread. Ing conto ing ngisor iki, siswa pengin nggawe animasi gambar nggunakake antarmuka Runnable, nanging dheweke kelalen miwiti thread. Conto sing salah
public class AnimCanvas extends Canvas implements Runnable {
        protected Thread myThread;
        public AnimCanvas() {
                myThread = new Thread(this);
        }

        // метод run() не будет вызван,
        // потому что поток не запущен.
        public void run() {
                for(int n = 0; n < 10000; n++) {
                   try {
                     Thread.sleep(100);
                   } catch (InterruptedException e) { }

                   animateStep(n);
                }
        }
        ...
}
Tuladha sing dibenerake:
public class AnimCanvas extends Canvas implements Runnable {
        static final int LIMIT = 10000;
        protected Thread myThread;

        public AnimCanvas() {
                myThread = new Thread(this);
                myThread.start();
        }

        public void run() {
                for(int n = 0; n < LIMIT; n++) {
                        try {
                          Thread.sleep(100);
                        } catch (InterruptedException e) { }

                        animateStep(n);
                }
        }
        ...
}
Siklus urip saka thread lan hubungan antarane thread lan kelas sing ngleksanakake antarmuka Runnableminangka bagéyan penting banget saka program Java, lan iku bakal migunani kanggo fokus ing.

18. Nggunakake metode readLine() sing dilarang saka kelas java.io.DataInputStream

readLine()Ing Jawa versi 1.0, sampeyan kudu nggunakake metode kelas kanggo maca string teks java.io.DataInputStream. Versi Jawa 1.1 nambahake kabeh kelas I / O kanggo nyedhiyakake operasi I / O kanggo teks: Readerlan Writer. Dadi, saka versi 1.1 kanggo maca baris teks, sampeyan kudu nggunakake metode readLine()kelas java.io.BufferedReader. Siswa bisa uga ora ngerti babagan owah-owahan iki, utamane yen diwulang saka buku lawas. (kira-kira. Terjemahan: bener-bener ora cocog maneh. Ora mungkin wong saiki bakal sinau saka buku sing umure 10 taun). Cara lawas readLine()tetep ana ing JDK, nanging diumumake ilegal, sing asring mbingungake siswa. Sing kudu dimangerteni yaiku nggunakake metode readLine()kelas java.io.DataInputStreamora salah, mung ketinggalan jaman. Sampeyan kudu nggunakake kelas BufferedReader. Tuladha sing salah:
public class LineReader {
    private DataInputStream dis;

    public LineReader(InputStream is) {
        dis = new DataInputStream(is);
    }

    public String getLine() {
        String ret = null;

        try {
          ret = dis.readLine();  // Неправильно! Запрещено.
        } catch (IOException ie) { }

        return ret;
    }
}
Tuladha sing dibenerake:
public class LineReader {
    private BufferedReader br;

    public LineReader(InputStream is) {
        br = new BufferedReader(new InputStreamReader(is));
    }

    public String getLine() {
        String ret = null;

        try {
          ret = br.readLine();
        } catch (IOException ie) { }

        return ret;
    }
}
Ana cara liyane sing dilarang ing versi luwih saka 1.0, nanging iki sing paling umum.

19. Nggunakake pindho minangka float

Kaya basa liyane, Jawa ndhukung operasi ing nomer floating point (nomer pecahan). Jawa nduweni rong jinis primitif kanggo angka floating-point: doubleIEEE 64-bit precision, lan floatIEEE 32-bit precision. Kangelan iku nalika nggunakake angka desimal kayata 1.75, 12.9e17 utawa -0.00003 - compiler nemtokake kanggo ngetik double. Jawa ora nindakake jinis cast ing operasi ngendi mundhut presisi bisa kelakon. Casting jinis iki kudu ditindakake dening programmer. Contone, Jawa ora ngidini sampeyan nemtokake nilai jinis menyang intvariabel jinis bytetanpa jinis cast, kaya sing ditampilake ing conto ing ngisor iki.
byte byteValue1 = 17; /* неправильно! */
byte byteValue2 = (byte)19; /* правильно */
Wiwit nomer pecahan dituduhake dening jinis double, lan assignment doublekanggo variabel saka jinis floatbisa mimpin kanggo mundhut saka tliti, compiler bakal sambat babagan sembarang nyoba kanggo nggunakake nomer pecahan minangka float. Dadi nggunakake tugas ing ngisor iki bakal nyegah kelas saka kompilasi.
float realValue1 = -1.7;          /* неправильно! */
float realValue2 = (float)(-1.9); /* правильно */
Tugas iki bisa digunakake ing C utawa C ++, nanging ing Jawa luwih kenceng. Ana 3 cara kanggo nyisihake kesalahan iki. Sampeyan bisa nggunakake jinis doubletinimbang float. Iki minangka solusi sing paling gampang. Nyatane, ora ana gunane nggunakake aritmetika 32-bit tinimbang 64-bit; prabédan kacepetan isih dipangan dening JVM (saliyane, ing prosesor modern kabeh angka pecahan diowahi dadi format prosesor 80-bit. ndhaptar sadurunge operasi apa wae). Mung kauntungan saka nggunakake iku floatpadha njupuk munggah memori kurang, kang migunani nalika nggarap nomer akeh variabel pecahan. Sampeyan bisa nggunakake modifier jinis nomer kanggo ngandhani compiler carane nyimpen nomer. Modifier kanggo jinis float - 'f'. Mangkono, compiler bakal nemtokake jinis 1.75 kanggo double, lan 1.75f - float. Tuladhane:
float realValue1 = 1.7;    /* неправильно! */
float realValue2 = 1.9f;   /* правильно */
Sampeyan bisa nggunakake casting jinis eksplisit. Iki minangka cara sing paling ora elegan, nanging migunani nalika ngowahi variabel jinis doubledadi jinis float. Tuladha:
float realValue1 = 1.7f;
double realValue2 = 1.9;
realValue1 = (float)realValue2;
Sampeyan bisa maca liyane babagan nomer floating point kene lan kene.

-- komentar penerjemah --
Mekaten.
Ing conto 10, kesalahan 9 bener digawe. Aku langsung weruh, nanging kelalen nulis cathetan. nanging ora dibenerake supaya ora ana bedo karo sumber asline.

Pengarang: A.Grasoff™ Link menyang sumber: Kesalahan programer java pemula
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION