JavaRush /Java Blogu /Random-AZ /Yeni başlayan java proqramçılarının səhvləri. 1-ci hissə
articles
Səviyyə

Yeni başlayan java proqramçılarının səhvləri. 1-ci hissə

Qrupda dərc edilmişdir

1. Sinfin adı onun saxlandığı faylın adından fərqlidir

İstifadə etdiyim bütün java çərçivələri, o cümlədən Javasoft JDK-ları, ümumi dəyişdiricisi olan sinif üçün mənbə kodunun sinif adı və .java uzantısı ilə tam olaraq eyni ada malik faylda saxlandığını güman edir. Bu konvensiyaya əməl edilməməsi kompilyasiya zamanı görünəcək bir çox problemə səbəb ola bilər.
Yeni başlayan java proqramçılarının səhvləri.  1-1 hissə
Yeni başlayan tələbələr (proqramçılar) çox vaxt bu konvensiyanı unudurlar və məsələn, tapşırığa uyğun olaraq fayl adını təyin edirlər: Lab6.java. Səhv nümunə: Fayl adıLab6.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Düzəliş edilmiş nümunə: Fayl adıAirplane.java
public class Airplane extends Vehicle
  Seat pilot;
  public Airplane() {
    pilot = new Seat();
  }
}
Xahiş edirəm qeyd edin:sinif adının böyük hərflə başlaması nəzərdə tutulur. Fayl adlarında hərf-həssas olan əməliyyat sistemləri, xüsusilə DOS fayl adlandırma sisteminə öyrəşmiş Unix-də Java öyrənən tələbələr üçün əlavə problemlər yarada bilər. Sinif MotorVehiclefaylda saxlanılmalıdır MotorVehicle.java, lakin bir faylda deyil motorvehicle.java.

2. Müqayisə istifadə edərək==

Java-da sətirlər sinifin obyektləridir java.lang.String. ==Obyektlərə müraciət edən operator obyektlərə istinadların bərabərliyini yoxlayır! Bəzən tələbələr operatorun semantikasını başa düşmür ==və sətirləri müqayisə etmək üçün ondan istifadə etməyə çalışırlar. Səhv nümunə:
// проверим, equals ли первый аргумент "-a"
if (args[0] == "-a") {
    optionsAll = true;
}
equals()Bərabərlik üçün 2 sətri müqayisə etməyin düzgün yolu sinif metodundan istifadə etməkdir java.lang.String. trueSətirlər eyni uzunluqdadırsa və eyni simvolları ehtiva edirsə, o, qaytarır . (Qeyd: əslində bu bərabərliyə zəmanət vermir. Əslində, equals2 sətirin simvollara görə bərabər olub olmadığını yoxlayır) Düzəliş edilmiş misal:
//  проверим, equals ли первый аргумент "-a"
if ("-a".equals(args[0])) {
    optionsAll = true;
}
Bu səhv axmaqdır, çünki əslində Java kodu sintaktik olaraq düzgün çıxır, amma sonda gözlənildiyi kimi işləmir. Bəzi tələbələr sinif metodu əvəzinə >və müqayisə operatorlarından da istifadə etməyə çalışırlar . Bu səhvi aşkar etmək daha asandır, çünki kompilyasiya mərhələsində səhvlərə səbəb olur. <=compareTo()java.lang.String

3. Massivin elementləri olan obyektləri işə salmağı unutmusunuz.

Java-da obyektlər massivi əslində obyekt istinadları massividir. Massiv yaratmaq sadəcə olaraq heç nəyə işarə etməyən istinadlar toplusunu yaratmaqdır (yəni onlar sıfırdır). Əslində obyektlərin "tam" massivini yaratmaq üçün siz massivin hər bir elementini işə salmalısınız. Bir çox tələbələr bunu başa düşmürlər; onlar hesab edirlər ki, obyektlər massivi yaratmaqla onlar avtomatik olaraq obyektləri özləri yaradırlar. (Əksər hallarda tələbələr bu konsepsiyanı C++ dilindən gətirirlər, burada obyektlər massivinin yaradılması onların standart konstruktorunu çağıraraq obyektlərin özlərini yaratmaqla nəticələnir.) Aşağıdakı nümunədə şagird sinifin 3 obyektini yaratmaq istəyir StringBuffer. Kod səhvsiz tərtib ediləcək, lakin NullPointerExceptionmövcud olmayan obyektə daxil olan son sətirdə istisna baş verəcəkdir. Səhv nümunə:
// Создаем массив из StringBuffer
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
myTempBuffers[0].add(data);
Bu xətanın qarşısını almaq üçün massiv elementlərini işə salmağı unutmayın. Düzəliş edilmiş nümunə:
// Создаем массив из StringBuffer и инициализируем элементы
StringBuffer [] myTempBuffers;
myTempBuffers = new StringBuffer[3];
for (int ix = 0; ix < myTempBuffers.length; ix++)
     myTempBuffers[ix] = new StringBuffer();

myTempBuffers[0].add(data);

4. Dəyişdirici ilə bir neçə sinfin bir faylda eyni vaxtda yerləşdirilməsipublic

Java mənbə faylları müəyyən şəkildə həmin fayllarda olan siniflərlə əlaqələndirilir. Əlaqəni aşağıdakı kimi xarakterizə etmək olar: İstənilən Java sinfi birdən çox olmayan faylda saxlanılır. İstənilən mənbə kodu faylında siz dəyişdirici ilə 1-dən çox olmayan sinif yerləşdirə bilərsiniz public. Mənbə kodu faylında dəyişdiricisi olan sinif varsa public, fayl adı və sinif adı ciddi şəkildə eyni olmalıdır (tərcümə qeydi: hər halda, 1-ci bəndə baxın) Bəzən tələbələr 2-ci qaydanı unudurlar, bu da səhvlərə səbəb olur. tərtib mərhələsində. 2-ci və 3-cü qaydalar üçün səhv mesajı eyni olacaq (bu, əslində bu xətanı tanımağı çətinləşdirir).

5. Sinif sahəsinin lokal dəyişənlə əvəz edilməsi.

Java, adı sinif sahələrinə uyğun gələn bir metod daxilində dəyişənləri elan etməyə imkan verir. Bu halda, yerli dəyişənlər üstünlük təşkil edəcək və sahələr əvəzinə istifadə olunacaq. Eyni ada malik dəyişənlər müxtəlif növlərdə olarsa, kompilyator xəta verəcək. Eyni növlərdirsə, tərtib etmə xətası olmayacaq və proqramın səhv işləməsinin səbəbləri aydın olmayacaq. Səhv nümunə:
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;
    }
}
Bu səhvi düzəltməyin bir neçə yolu var. Ən sadəsi gizli göstəricidən istifadə edərək sinif sahələrinə daxil olmaqdır this: this.Name_поля. Ən yaxşı yol sinif sahəsinin və ya yerli dəyişənin adını dəyişməkdir, onda əvəzetmə baş verməyəcək. (təqribən. Tərcümə: 2-ci üsul bizim metodumuz deyil. Üstəlik, bu, nə vaxtsa dəyişən sahəsini təsadüfən əvəz etməyəcəyimə zəmanət vermir. Vərəsəlikdə daha böyük çətinlik yaranır, hansı sahələri ümumiyyətlə görmədim. sinif var ) Düzəliş edilmiş nümunə:
// 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;
  }
Bu xətanın baş verməsi üçün başqa mümkün yer metod parametrinin adını sinif sahəsinin adı ilə eyni etməkdir. Bu konstruktorlarda yaxşı görünür, lakin normal metodlar üçün uyğun deyil.

təqribən. tərcümə

bir az xaotik, amma əsas budur

public class Test {
   private int param = 0;

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

yəni konstruktorda hər şey gözəl görünür, lakin bu adi üsullar üçün istifadə edilməməlidir.

6. Ana (superclass) konstruktora zəng etməyi unutmuşam

Bir sinif başqa bir sinfi genişləndirdikdə, hər bir alt sinif konstruktoru bəzi superclass konstruktorunu çağırmalıdır. super(x)Bu adətən konstruktorun birinci sətirində yerləşdirilmiş metodla superclass konstruktorunu çağırmaqla əldə edilir . Əgər konstruktorun birinci sətrində çağırış yoxdursa super(x), kompilyator özü bu çağırışı daxil edir, lakin parametrlərsiz: super(). (təxminən trans.: x...se, amma bilmədim) Bəzən tələbələr bu tələbi unudurlar. Adətən bu problem deyil: superclass konstruktoruna zəng kompilyator tərəfindən daxil edilir və hər şey yaxşı işləyir. Bununla belə, əgər supersinif standart konstruktora malik deyilsə, kompilyator xəta atacaq. Aşağıdakı nümunədə bütün supersinif konstruktorlarının java.io.File1 və ya 2 parametri var: Səhv nümunə:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        classname = cl;
    }
}
Problemin həlli düzgün superclass konstruktoruna açıq çağırış daxil etməkdir: Düzəliş edilmiş nümunə:
public class JavaClassFile extends File {
    String classname;
    public JavaClassFile(String cl) {
        super(cl + ".class");
        classname = cl;
    }
}
Daha xoşagəlməz vəziyyət o zaman baş verir ki, supersinif standart konstruktora malikdir, lakin o, obyekti tam işə salmır. Bu halda kod tərtib olunacaq, lakin proqramın çıxışı səhv ola bilər və ya istisna baş verə bilər.

7. İstisnaların səhv tutulması

Java-nın istisnalarla işləmə sistemi olduqca güclüdür, lakin yeni başlayanlar üçün başa düşmək çətindir. C++ və ya Ada dilini bilən tələbələr adətən C və Fortran proqramçıları ilə eyni çətinliklərlə üzləşmirlər. Aşağıdakı nümunələr bəzi ümumi səhvləri göstərir. Bu misalda istisna adlanmayıb. Kompilyator bu səhvi kompilyasiya mərhələsində göstərəcək, ona görə də onu özünüz düzəltmək asandır. Səhv nümunə:
try {
    stream1 = new FileInputStream("data.txt");
} catch (IOException) {
    message("Could not open data.txt");
}
Düzəliş edilmiş nümunə:
try {
   stream1 = new FileInputStream("data.txt");
} catch (IOException ie) {
   message("Could not open data.txt: " + ie);
}
Blokların sırası catchistisnaların tutulma sırasını müəyyən edir. Nəzərə almaq lazımdır ki, hər bir belə blok göstərilən sinfin və ya onun hər hansı alt sinifinin bütün istisnalarını tutacaq. Bunu nəzərə almasanız, kompilyatorun qeyd edəcəyi əlçatmaz tutma bloku ilə nəticələnə bilərsiniz. Aşağıdakı nümunədə SocketExceptionbir alt sinifdir IOException. Səhv nümunə:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (IOException ie) {
    message("Error accepting connection.");
} catch (SocketException se) {
    message("Error setting time-out.");
}
Düzəliş edilmiş nümunə:
try {
    serviceSocket.setSoTimeout(1000);
    newsock = serviceSocket.accept();
} catch (SocketException se) {
    message("Error setting time-out.");
} catch (IOException ie) {
    message("Error accepting connection.");
}
Əgər kodunuzda heç bir blok tərəfindən tutulmayan bir istisnanın baş verməsi mümkündürsə try-catch, bu istisna metodun başlığında elan edilməlidir. RuntimeException(İstisnalar üçün bu lazım deyil - sinfin alt sinifləri ). Tələbələr bəzən unudurlar ki, metodu çağırmaq istisna yarada bilər. Bunu düzəltməyin ən asan yolu metod çağırışını bloka yerləşdirməkdir try-catch. Səhv nümunə:
public void waitFor(int sec) {
    Thread.sleep(sec * 1000);
}
Düzəliş edilmiş nümunə:
public void waitFor(int sec) throws InterruptedException {
    Thread.sleep(sec * 1000);
}

8. Giriş metodunun bir növü varvoid

Bu çox sadə səhvdir. Şagird dəyişənə daxil olmaq üçün metod yaradır, lakin metodun heç nə qaytarmadığını müəyyən edir ( voidmetod başlığına dəyişdirici yerləşdirir). Bu səhvi düzəltmək üçün düzgün qaytarma növünü göstərməlisiniz. Səhv nümunə:
public class Line {
    private Point start, end;
    public void getStart() {
      return start;
    }
}
Düzəliş edilmiş nümunə:
public class Line {
    private Point start, end;
    public Point getStart() {
      return start;
    }
}
Səhv qaytarma növünün təyin edilməsi bütün səhv sinifini yaradır. Tipik olaraq, tərtibçi bu səhvləri tanıyacaq və tələbələrin özləri onları düzəldə bilməsi üçün hesabat verəcəkdir. Müəllif: A. Grasoff™ Davamını oxuyun Mənbəyə keçid: Yeni başlayan java proqramçılarının səhvləri
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION