JavaRush /Java blogi /Random-UZ /Yangi boshlanuvchi java dasturchilarining xatolari. 1-qis...
articles
Daraja

Yangi boshlanuvchi java dasturchilarining xatolari. 1-qism

Guruhda nashr etilgan

1. Sinf nomi u saqlanadigan fayl nomidan farq qiladi

Men foydalangan barcha java ramkalar, jumladan Javasoft JDK’lar, umumiy o‘zgartiruvchisi bo‘lgan sinfning manba kodi sinf nomi va .java kengaytmasi bilan aynan bir xil nomga ega faylda saqlangan deb faraz qiladi. Ushbu konventsiyaga rioya qilmaslik kompilyatsiya paytida paydo bo'ladigan ko'plab muammolarni keltirib chiqarishi mumkin.
Yangi boshlanuvchi java dasturchilarining xatolari.  1-1-qism
Boshlang'ich talabalar (dasturchilar) ko'pincha ushbu konventsiyani unutishadi va masalan, topshiriqga muvofiq fayl nomini o'rnatadilar: Lab6.java. Noto'g'ri misol: fayl nomiLab6.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Tuzatilgan misol: Fayl nomiAirplane.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Esda tuting:sinf nomi bosh harf bilan boshlanadi deb taxmin qilinadi. Fayl nomlarida katta-kichik harflarga sezgir bo'lgan operatsion tizimlar, ayniqsa, DOS fayl nomlash tizimiga o'rganib qolgan Unix-da Java tilini o'rganayotgan talabalar uchun qo'shimcha muammolarni keltirib chiqarishi mumkin. Sinf MotorVehiclefaylda saqlanishi kerak MotorVehicle.java, lekin faylda emas motorvehicle.java.

2. Taqqoslash yordamida==

Java-da satrlar sinfning ob'ektlari hisoblanadi java.lang.String. ==Ob'ektlarga murojaat qilgan operator ob'ektlarga havolalar tengligini tekshiradi! Ba'zan talabalar operatorning semantikasini tushunmaydilar ==va satrlarni solishtirish uchun undan foydalanishga harakat qilishadi. Noto'g'ri misol:
// проверим, equals ли первый аргумент "-a"
if (args[0] == "-a") {
    optionsAll = true;
}
equals()Tenglik uchun 2 ta satrni solishtirishning to'g'ri yo'li sinf usulidan foydalanishdir java.lang.String. trueAgar satrlar bir xil uzunlikda va bir xil belgilarni o'z ichiga olgan bo'lsa, u qaytadi . (Eslatma: aslida bu tenglikni kafolatlamaydi. Aslida equalsu 2 satrning belgi boʻyicha teng ekanligini tekshiradi) Tuzatilgan misol:
//  проверим, equals ли первый аргумент "-a"
if ("-a".equals(args[0])) {
    optionsAll = true;
}
Bu xato ahmoqdir, chunki aslida Java kodi sintaktik jihatdan to'g'ri bo'lib chiqadi, lekin oxirida u kutilganidek ishlamaydi. Ba'zi talabalar sinf usuli o'rniga >va taqqoslash operatorlarini ham ishlatishga harakat qilishadi . Ushbu xatoni aniqlash osonroq, chunki u kompilyatsiya bosqichida xatolarga olib keladi. <=compareTo()java.lang.String

3. Massiv elementlari bo'lgan ob'ektlarni ishga tushirishni unutgan.

Java-da ob'ektlar massivi aslida ob'ektga havolalar massividir. Massiv yaratish shunchaki hech narsaga ishora qilmaydigan havolalar to'plamini yaratishdir (ya'ni ular null). Haqiqatan ham "to'liq" ob'ektlar majmuasini yaratish uchun siz massivning har bir elementini ishga tushirishingiz kerak. Ko'pgina talabalar buni tushunmaydilar; ob'ektlar massivini yaratish orqali ular avtomatik ravishda ob'ektlarni o'zlari yaratadilar, deb hisoblashadi. (Ko'p hollarda talabalar ushbu kontseptsiyani C++ tilidan olib kelishadi, bunda ob'ektlar massivini yaratish ularning standart konstruktorini chaqirish orqali ob'ektlarning o'zini yaratishga olib keladi.) Quyidagi misolda talaba sinfning 3 ta ob'ektini yaratmoqchi StringBuffer. Kod xatosiz kompilyatsiya qilinadi, lekin NullPointerExceptionmavjud bo'lmagan ob'ektga kirish mumkin bo'lgan oxirgi qatorda istisno paydo bo'ladi. Noto'g'ri misol:
// Создаем массив из StringBuffer
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
myTempBuffers[0].add(data);
Ushbu xatolikka yo'l qo'ymaslik uchun massiv elementlarini ishga tushirishni unutmang. To'g'rilangan misol:
// Создаем массив из StringBuffer и инициализируем элементы
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
for (int ix = 0; ix < myTempBuffers.length; ix++)
     myTempBuffers[ix] = new StringBuffer();

myTempBuffers[0].add(data);

4. Bir faylga bir vaqtning o'zida modifikatorli bir nechta sinflarni joylashtirishpublic

Java manba fayllari ma'lum bir tarzda ushbu fayllar tarkibidagi sinflar bilan bog'langan. Munosabatni quyidagicha tavsiflash mumkin: Har qanday Java klassi bir nechta faylda saqlanadi. Har qanday manba kodi faylida modifikator bilan 1 dan ortiq bo'lmagan sinfni joylashtirishingiz mumkin public. Agar manba kod faylida modifikatorli sinf mavjud bo'lsa public, fayl nomi va sinf nomi mutlaqo bir xil bo'lishi kerak (tarjima eslatmasi: holatga qadar, 1-bandga qarang) Ba'zida o'quvchilar 2-qoidani unutishadi, bu esa xatolarga olib keladi. kompilyatsiya bosqichida. 2 va 3-qoidalar uchun xato xabari bir xil bo'ladi (bu xatoni tanib olishni qiyinlashtiradigan narsa).

5. Klass maydonini mahalliy o'zgaruvchiga almashtirish.

Java o'zgaruvchilarni nomi sinf maydonlariga mos keladigan usul ichida e'lon qilish imkonini beradi. Bunday holda, mahalliy o'zgaruvchilar ustunlik qiladi va maydonlar o'rniga ishlatiladi. Agar bir xil nomdagi o'zgaruvchilar turli xil bo'lsa, kompilyator xato qiladi. Agar ular bir xil turdagi bo'lsa, kompilyatsiya xatosi bo'lmaydi va dasturning noto'g'ri ishlashining sabablari noaniq bo'ladi. Noto'g'ri misol:
public class Point3 {
    int i = 0;
    int j = 0;
    int k = 0;

    public boolean hits(Point[] p2list) {
      for(int i = 0; i < p2list.length; i++) {
        Point p2 = p2list[i];
        if (p2.x == i && p2.y == j)
          return true;
      }
      return false;
    }
}
Ushbu xatoni tuzatishning bir necha yo'li mavjud. thisEng oddiy yo'q : ko'rsatgich yordamida sinf maydonlariga kirish this.Name_поля. Eng yaxshi usul - sinf maydoni yoki mahalliy o'zgaruvchining nomini o'zgartirish, keyin almashtirish sodir bo'lmaydi. (taxminan. Tarjima.: 2-usul bizning usul emas. Qolaversa, men qachondir oʻzgaruvchining maydonini tasodifan almashtirmasligimga kafolat bermaydi. Qachonki, qaysi sohalarni umuman koʻrmasam, merosxoʻrlikda bundan ham kattaroq qiyinchilik tugʻiladi. sinfda ) To'g'rilangan misol:
// One way to fix the problem
  int i = 0;
  int j = 0;
  int k = 0;

  public boolean hits(Point[] p2list) {
    for(int i = 0; i < p2list.length; i++) {
      Point p2 = p2list[i];
      if (p2.x == this.i && p2.y == this.j)
        return true;
    }
    return false;
  }

  // *****************************
  // Лучший способ
  int x = 0;
  int y = 0;
  int z = 0;

  public boolean hits(Point[] p2list) {
    for(int i = 0; i < p2list.length; i++) {
      Point p2 = p2list[i];
      if (p2.x == x && p2.y == y)
        return true;
    }
    return false;
  }
Ushbu xato yuzaga kelishi mumkin bo'lgan boshqa joy - bu usul parametrining nomini sinf maydoni nomi bilan bir xil qilib o'rnatish. Bu konstruktorlarda yaxshi ko'rinadi, lekin oddiy usullar uchun mos emas.

taxminan. tarjima

biroz xaotik, lekin buning mohiyati

public class Test {
   private int param = 0;

   public Test(int param) {
      this.param = param;
   }
}

ya'ni konstruktorda hamma narsa chiroyli ko'rinadi, lekin bu oddiy usullar uchun ishlatilmasligi kerak.

6. Ota (supersinf) konstruktoriga qo'ng'iroq qilishni unutdingiz

Agar sinf boshqa sinfni kengaytirsa, har bir subklass konstruktori superklass konstruktorini chaqirishi kerak. super(x)Bunga odatda konstruktorning birinchi qatoriga joylashtirilgan usul bilan superklass konstruktorini chaqirish orqali erishiladi . Agar konstruktorning birinchi qatorida qo'ng'iroq bo'lmasa super(x), kompilyatorning o'zi bu qo'ng'iroqni kiritadi, lekin parametrlarsiz: super(). (taxminan trans.: x...se, lekin men bilmadim) Ba'zida talabalar bu talabni unutishadi. Odatda bu muammo emas: superklass konstruktoriga qo'ng'iroq kompilyator tomonidan kiritiladi va hamma narsa yaxshi ishlaydi. Biroq, agar superklassda standart konstruktor bo'lmasa, kompilyator xatoga yo'l qo'yadi. Quyidagi misolda barcha superklass konstruktorlari java.io.File1 yoki 2 parametrga ega: Xato misol:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        classname = cl;
    }
}
Muammoni hal qilish to'g'ri superklass konstruktoriga aniq qo'ng'iroqni kiritishdir: Tuzatilgan misol:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        super(cl + ".class");
        classname = cl;
    }
}
Ko'proq noxush holat superklassda standart konstruktor mavjud bo'lganda yuzaga keladi, lekin u ob'ektni to'liq ishga tushirmaydi. Bunday holda, kod kompilyatsiya qilinadi, lekin dasturning chiqishi noto'g'ri bo'lishi yoki istisno bo'lishi mumkin.

7. Istisnolarni noto'g'ri ushlash

Java-ning istisnolarni boshqarish tizimi juda kuchli, ammo yangi boshlanuvchilar uchun tushunish qiyin. C++ yoki Ada tilini yaxshi biladigan talabalar odatda C va Fortran dasturchilari kabi qiyinchiliklarga duch kelmaydilar. Quyidagi misollar ba'zi keng tarqalgan xatolarni ko'rsatadi. Ushbu misolda istisno nomlanmagan. Kompilyator bu xatoni kompilyatsiya bosqichida ko'rsatadi, shuning uchun uni o'zingiz tuzatishingiz oson. Noto'g'ri misol:
try {
    stream1 = new FileInputStream("data.txt");
} catch (IOException) {
    message("Could not open data.txt");
}
To'g'rilangan misol:
try {
   stream1 = new FileInputStream("data.txt");
} catch (IOException ie) {
   message("Could not open data.txt: " + ie);
}
Bloklarning tartibi catchistisnolarni ushlash tartibini belgilaydi. Shuni hisobga olish kerakki, har bir bunday blok ko'rsatilgan sinf yoki uning har qanday kichik sinfining barcha istisnolarini ushlaydi. Agar buni hisobga olmasangiz, kompilyator ko'rsatib bo'lmaydigan catch blokiga ega bo'lishingiz mumkin. Quyidagi misolda ning SocketExceptionkichik sinfi mavjud IOException. Noto'g'ri misol:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (IOException ie) {
    message("Error accepting connection.");
} catch (SocketException se) {
    message("Error setting time-out.");
}
To'g'rilangan misol:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (SocketException se) {
    message("Error setting time-out.");
} catch (IOException ie) {
    message("Error accepting connection.");
}
Agar kodingizda biron bir blok tomonidan ushlanmagan istisno yuzaga kelishi mumkin bo'lsa try-catch, bu istisno usul sarlavhasida e'lon qilinishi kerak. RuntimeException( Bu istisnolar uchun kerak emas - sinfning pastki sinflari ). Talabalar ba'zida usulni chaqirish istisnoga olib kelishi mumkinligini unutishadi. Buni tuzatishning eng oson yo'li usul chaqiruvini blokga qo'yishdir try-catch. Noto'g'ri misol:
public void waitFor(int sec) {
    Thread.sleep(sec * 1000);
}
To'g'rilangan misol:
public void waitFor(int sec) throws InterruptedException {
    Thread.sleep(sec * 1000);
}

8. Kirish usuli turiga egavoid

Bu juda oddiy xato. Talaba o'zgaruvchiga kirish usulini yaratadi, lekin bu usul hech narsani qaytarmasligini belgilaydi ( voidmetod sarlavhasiga modifikatorni joylashtiradi). Ushbu xatoni tuzatish uchun siz to'g'ri qaytish turini ko'rsatishingiz kerak. Noto'g'ri misol:
public class Line {
    private Point start, end;
    public void getStart() {
      return start;
    }
}
To'g'rilangan misol:
public class Line {
    private Point start, end;
    public Point getStart() {
      return start;
    }
}
Noto'g'ri qaytish turini belgilash xatolarning butun sinfini hosil qiladi. Odatda kompilyator bu xatolarni tan oladi va o'quvchilar ularni o'zlari tuzatishi uchun ular haqida xabar beradi. Muallif: A. Grasoff™ Davomini o'qing. Manbaga havola: Yangi boshlanuvchi java dasturchilarining xatolari
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION