3-bo‘lim

Turlar va o'zgaruvchilar

Primitiv va havola turlari, butun va kasr sonlar, BigDecimal, var va final, turlarni aylantirish, avtoqutilash va Integer keshi tuzog'i.

🕑 15 daqiqa o‘qish 📄 866 so‘z 👁 1 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Primitiv turlar
  2. To'lib ketish
  3. Primitiv va havola turlari
  4. Kasr sonlar va aniqlik
  5. var - turni kompilyator aniqlaydi
  6. final
  7. Turlarni aylantirish
  8. Avtoqutilash va Integer keshi
  9. Xulosa

Java qat'iy turlangan til: har bir o'zgaruvchining turi bor va u o'zgarmaydi. Bu ko'proq yozishni talab qiladi, lekin xatolarning katta qismini ishga tushirishdan oldin topadi.

Primitiv turlar #

Java'da sakkizta primitiv tur bor. Ular obyekt emas - shunchaki qiymat.

TurHajmiDiapazon yoki maqsad
byte1 bayt-128 .. 127
short2 bayt-32 768 .. 32 767
int4 bayt±2 milliardgacha - odatiy tanlov
long8 baytJuda katta butun sonlar
float4 baytKasr son, kam aniqlik
double8 baytKasr son - odatiy tanlov
char2 baytBitta belgi: 'A'
boolean-true yoki false

Chegaralarni o'zingiz ko'rishingiz mumkin:

Java
public class Chegaralar {
    public static void main(String[] args) {
        System.out.println("int:  " + Integer.MIN_VALUE
                + " .. " + Integer.MAX_VALUE);
        System.out.println("long: " + Long.MIN_VALUE
                + " .. " + Long.MAX_VALUE);
        System.out.println("byte: " + Byte.MIN_VALUE
                + " .. " + Byte.MAX_VALUE);
    }
}
Natija
int:  -2147483648 .. 2147483647
long: -9223372036854775808 .. 9223372036854775807
byte: -128 .. 127

To'lib ketish #

Java
public class Tolish {
    public static void main(String[] args) {
        int katta = Integer.MAX_VALUE;
        System.out.println("MAX_VALUE:     " + katta);
        System.out.println("MAX_VALUE + 1: " + (katta + 1));

        long togri = (long) katta + 1;
        System.out.println("long bilan:    " + togri);
    }
}
Natija
MAX_VALUE:     2147483647
MAX_VALUE + 1: -2147483648
long bilan:    2147483648
To'lish jimgina yuz beradi

int chegarasidan oshganda Java xato bermaydi - son eng kichik qiymatga "aylanib" o'tadi.

Bu haqiqiy tizimlarda jiddiy xatolarga sabab bo'lgan. Masalan millisekundlarni int da saqlasangiz, 24 kundan keyin to'lib ketadi.

Ikki himoya usuli:

  1. Katta bo'lishi mumkin bo'lgan qiymatlar uchun long ishlating;
  2. Tekshiruv kerak bo'lsa Math.addExact chaqiring - u to'lishda istisno tashlaydi.
Java
public class Xavfsiz {
    public static void main(String[] args) {
        try {
            Math.addExact(Integer.MAX_VALUE, 1);
        } catch (ArithmeticException x) {
            System.out.println("Ushlandi: " + x.getMessage());
        }
    }
}
Natija
Ushlandi: integer overflow

Primitiv va havola turlari #

Bu Java'dagi eng muhim ajratish.

Xotirada qanday saqlanadi Primitiv (int, double, boolean) int a = 5; int b = a; b = 9; a 5 b 9 a = 5, b = 9 Qiymat nusxalanadi - ikki mustaqil katak Havola (massiv, sinf, String) int[] x = {5}; int[] y = x; y[0] = 9; x y bitta massiv [9] x[0] = 9, y[0] = 9 Faqat manzil nusxalanadi
Primitiv qiymat nusxalanadi, havolada esa faqat manzil nusxalanadi
Java
import java.util.Arrays;

public class Turlar {
    public static void main(String[] args) {
        int a = 5;
        int b = a;
        b = 9;
        System.out.println("Primitiv: a = " + a + ", b = " + b);

        int[] x = {5};
        int[] y = x;
        y[0] = 9;
        System.out.println("Havola:   x = " + Arrays.toString(x)
                + ", y = " + Arrays.toString(y));
    }
}
Natija
Primitiv: a = 5, b = 9
Havola:   x = [9], y = [9]
Java'da hamma narsa qiymat bo'yicha uzatiladi

Ko'p manbada "obyektlar havola bo'yicha uzatiladi" deb yoziladi. Bu noto'g'ri.

Java'da har doim qiymat nusxalanadi. Obyektlarda esa nusxalanadigan qiymat - bu havolaning o'zi, obyekt emas.

Farq amalda ko'rinadi:

Java
public class Uzatish {
    public static void main(String[] args) {
        int[] massiv = {1};
        Ozgartir(massiv);
        System.out.println("Element o'zgardi: " + massiv[0]);

        Almashtir(massiv);
        System.out.println("Massivning o'zi:  " + massiv[0]);
    }

    static void Ozgartir(int[] m) {
        m[0] = 99;                 // obyekt ichini o'zgartiradi
    }

    static void Almashtir(int[] m) {
        m = new int[]{777};        // faqat lokal nusxani almashtiradi
    }
}
Natija
Element o'zgardi: 99
Massivning o'zi:  99

Birinchi metod obyekt ichini o'zgartirdi - bu tashqarida ko'rindi. Ikkinchisi havolaning o'zini almashtirdi - bu faqat metod ichida qoldi.

Kasr sonlar va aniqlik #

Java
public class Kasr {
    public static void main(String[] args) {
        double a = 0.1;
        double b = 0.2;

        System.out.println("0.1 + 0.2 == 0.3 : " + (a + b == 0.3));
        System.out.println("Haqiqiy natija   : " + (a + b));
    }
}
Natija
0.1 + 0.2 == 0.3 : false
Haqiqiy natija   : 0.30000000000000004

double sonni ikkilik kasrda saqlaydi va 0.1 ni ikkilikda aniq ifodalab bo'lmaydi - xuddi 1/3 ni o'nlik kasrda aniq yozib bo'lmagani kabi.

Pul uchun hech qachon double ishlatmang

Pul hisobida bu xatolar to'planib, haqiqiy zararga aylanadi. Java'da buning uchun BigDecimal bor:

Java
import java.math.BigDecimal;

public class Pul {
    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("0.1");
        BigDecimal b = new BigDecimal("0.2");
        BigDecimal jami = a.add(b);

        System.out.println("Yig'indi: " + jami);
        System.out.println("0.3 ga tengmi: "
                + jami.equals(new BigDecimal("0.3")));
    }
}
Natija
Yig'indi: 0.3
0.3 ga tengmi: true

Ikkita muhim tafsilot:

  1. Satrdan yarating: new BigDecimal("0.1"). new BigDecimal(0.1) deb double bersangiz, o'sha aniqsizlik ichkariga kirib ketadi.
  2. + amali ishlamaydi - Java'da operator qayta yuklash yo'q. add, subtract, multiply metodlarini chaqirasiz.

var - turni kompilyator aniqlaydi #

Java 10 dan lokal o'zgaruvchi turini yozmaslik mumkin:

Java
import java.util.*;

public class Var {
    public static void main(String[] args) {
        var yosh = 25;                       // int
        var narx = 12.5;                     // double
        var ism = "Malika";                  // String
        var royxat = new ArrayList<String>();

        royxat.add("Namangan");

        System.out.println(ism + ": " + yosh);
        System.out.println("Ro'yxat: " + royxat);
        System.out.println("narx turi: "
                + ((Object) narx).getClass().getSimpleName());
    }
}
Natija
Malika: 25
Ro'yxat: [Namangan]
narx turi: Double

var turni yo'q qilmaydi - uni kompilyator o'ng tomondan aniqlaydi va keyin o'zgartirib bo'lmaydi.

var faqat lokal o'zgaruvchilar uchun

var ni quyidagi joylarda ishlatib bo'lmaydi:

  • sinf maydonlarida;
  • metod parametrlarida;
  • metod qaytish turida.

Bundan tashqari, var x = null; ham xato - kompilyator turni aniqlay olmaydi.

Qoida: o'ng tomonga qarab tur ko'rinib tursa var yozing (var royxat = new ArrayList<String>()), ko'rinmasa - to'liq turni yozing.

final #

Java
public class Doimiy {
    static final double PI_TAXMINAN = 3.14159;
    static final String MAKTAB = "14-maktab";

    public static void main(String[] args) {
        final int yosh = 25;
        System.out.println(MAKTAB + ", yosh: " + yosh);
        System.out.println("Aylana: " + (2 * PI_TAXMINAN * 5));
    }
}
Natija
14-maktab, yosh: 25
Aylana: 31.4159

final o'zgaruvchini bir marta o'zlashtirishga ruxsat beradi. Doimiy nomlari BOSH HARFLAR bilan yoziladi.

Turlarni aylantirish #

Java
public class Aylantirish {
    public static void main(String[] args) {
        int kichik = 42;
        long katta = kichik;          // kengaytirish - o'zi bo'ladi
        double kasr = kichik;

        System.out.println(katta + " va " + kasr);

        double narx = 19.99;
        int butun = (int) narx;       // toraytirish - oshkora yozish shart

        System.out.println(narx + " -> " + butun);
        System.out.println("Yaxlitlash: " + Math.round(narx));
    }
}
Natija
42 va 42.0
19.99 -> 19
Yaxlitlash: 20
(int) yaxlitlamaydi - kesib tashlaydi

(int) 19.99 natijasi 19, 20 emas. Oshkora aylantirish kasr qismini shunchaki tashlab yuboradi.

Yaxlitlash kerak bo'lsa Math.round ishlating. E'tibor bering: Math.round(double) natijasi long, Math.round(float) esa int qaytaradi.

Avtoqutilash va Integer keshi #

Java'da har bir primitiv turning obyekt ko'rinishi bor: intInteger, doubleDouble. Kompilyator ular orasida avtomatik o'tadi.

Java
public class Qutilash {
    public static void main(String[] args) {
        Integer a = 100;
        Integer b = 100;
        Integer c = 1000;
        Integer d = 1000;

        System.out.println("a == b  (100):  " + (a == b));
        System.out.println("c == d  (1000): " + (c == d));
        System.out.println("c.equals(d):    " + c.equals(d));
    }
}
Natija
a == b  (100):  true
c == d  (1000): false
c.equals(d):    true
Bu Java'ning eng mashhur tuzog'i

Bir xil kod, bir xil mantiq - lekin 100 uchun true, 1000 uchun false.

Sababi: JVM -128 dan 127 gacha bo'lgan Integer obyektlarini oldindan yaratib qo'yadi va qayta ishlatadi. Shu diapazonda a va b aynan bitta obyekt, shuning uchun == rost bo'ladi.

1000 esa har safar yangi obyekt - ikki xil manzil, == yolg'on.

Qoida: obyektlarni hech qachon == bilan solishtirmang. == faqat primitivlar uchun. Obyektlar uchun har doim equals.

Bu qoida String uchun ham amal qiladi va keyingi bo'limda yana qaytadi.

Qachon primitiv, qachon obyekt
HolatTanlov
Oddiy hisob, sikl hisoblagichiprimitiv (int)
Kolleksiyada saqlashobyekt (Integer) - boshqa yo'l yo'q
"Qiymat yo'q" holatini ifodalashobyekt - u null bo'la oladi
Tezlik muhim, million elementprimitiv - qutilash qimmat

List<int> deb yozib bo'lmaydi - faqat List<Integer>. Bu Java'ning tarixiy cheklovi.

Amaliy topshiriq
  1. Sakkizta primitiv turning har biri uchun o'zgaruvchi e'lon qiling.
  2. Integer.MAX_VALUE ga 1 qo'shib, natijani ko'ring.
  3. Math.addExact bilan to'lishni ushlang.
  4. Primitiv va havola nusxalanishini massiv misolida tekshiring.
  5. Metodga massiv uzatib, ichini o'zgartiring - tashqarida ko'rinishini ko'ring.
  6. 0.1 + 0.2 ni double va BigDecimal da solishtiring.
  7. new BigDecimal(0.1) va new BigDecimal("0.1") farqini ko'ring.
  8. var bilan to'rtta o'zgaruvchi yarating.
  9. Integer ni 100 va 1000 qiymatlarida == bilan solishtiring.
  10. Nega List<int> yozib bo'lmasligini tushuntiring.

Xulosa #

  • Java'da sakkizta primitiv tur bor; qolgan hamma narsa - obyekt.
  • int to'lib ketganda xato bermaydi - long yoki Math.addExact ishlating.
  • Primitiv qiymat nusxalanadi, obyektda esa havola nusxalanadi - lekin ikkala holatda ham uzatish qiymat bo'yicha.
  • double kasr sonlarni aniq saqlamaydi; pul uchun BigDecimal va uni satrdan yarating.
  • Java'da operator qayta yuklash yo'q - BigDecimal da add chaqiriladi.
  • var faqat lokal o'zgaruvchilar uchun.
  • (int) yaxlitlamaydi, kesadi; yaxlitlash uchun Math.round.
  • Obyektlarni == bilan solishtirmang - Integer keshi tufayli natija diapazonga bog'liq bo'lib qoladi.

Keyingi bo'limda satrlar bilan ishlashni o'rganamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.