JavaRush /Java блогу /Random-KY /Ошентип, акыркы ...
Алексей
Деңгээл

Ошентип, акыркы ...

Группада жарыяланган
Java тorнде ачкыч сөз бар - final. Аны класстарга, методдорго, өзгөрмөлөргө (анын ичинде метод аргументтерине) колдонсо болот. Ошентип финал... - 1Класс үчүн бул класстын субкласстары болушу мүмкүн эмес дегенди билдирет, б.а. Мураска тыюу салынат. Бул (өзгөрбөс) an objectтерди түзүүдө пайдалуу immutable, мисалы класс Stringкатары жарыяланган final.
public final class String{
}

class SubString extends String{ //Compilation error
}
Белгилей кетчү нерсе, модификатор абстракттуу класстарга колдонулbyte (ачкыч сөз менен abstract), finalанткени булар бири-бирин жокко чыгарган түшүнүктөр. Метод үчүн finalаны подкласстарда жокко чыгарууга болбойт дегенди билдирет. Бул баштапкы ишке ашыруунун жокко чыгарылбашы үчүн пайдалуу.
public class SuperClass{
    public final void printReport(){
        System.out.println("Report");
    }
}

class SubClass extends SuperClass{
    public void printReport(){  //Compilation error
        System.out.println("MyReport");
    }
}
Примитивдүү түрдөгү өзгөрмөлөр үчүн бул бир жолу дайындалгандан кийин маанини өзгөртүү мүмкүн эмес дегенди билдирет. Шилтеме өзгөрмөлөр үчүн бул an object дайындалгандан кийин, ал an objectке шилтемени өзгөртүү мүмкүн эмес дегенди билдирет. Бул маанилүү! Шилтемени өзгөртүү мүмкүн эмес, бирок an objectтин абалын өзгөртүүгө болот. Java 8 менен түшүнүк пайда болду - effectively final. Ал өзгөрмөлөргө гана тиешелүү (анын ичинде ыкма аргументтери). Кеп ачкыч сөздүн ачык-айкын жоктугуна карабастан final, инициализациядан кийин өзгөрмөнүн мааниси өзгөрбөйт. finalБашка сөз менен айтканда, сиз компиляция катасы жок мындай өзгөрмө сөздү алмаштыра аласыз . Өзгөрмөлөрдү жергorктүү класстардын ( ), анонимдүү класстардын ( ), агымдардын ( Stream API ) effectively finalичинде колдонсо болот .Local Inner ClassesAnonymous Inner Classes
public void someMethod(){
    // In the example below, both a and b are effectively final, since the values ​​are set once:
    int a = 1;
    int b;
    if (a == 2) b = 3;
    else b = 4;
    // c is NOT effectively final because value changes
    int c = 10;
    c++;

    Stream.of(1, 2).forEach(s-> System.out.println(s + a)); //Ок
    Stream.of(1, 2).forEach(s-> System.out.println(s + c)); //Compilation error
}
Эми кичине интервью алалы. Анткени, JavaRush курсунан өтүүнүн максаты - Java иштеп чыгуучусу болуу жана кызыктуу жана жакшы акы төлөнүүчү жумушка ээ болуу. Ошентип, баштайлы.
  1. Массив жарыяланганда ал жөнүндө эмне айта аласыз final?

  2. Белгилүү болгондой, класс String, immutableкласс жарыяланат , саптын мааниси ачкыч сөз менен белгиленген finalмассивде сакталат .charfinal

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
Объекттин маанисин алмаштыруу мүмкүнбү String(an objectке шилтемени өзгөртпөстөн)? Бул чыныгы интервью суроолору. Жана практика көрсөткөндөй, көптөр аларга туура эмес жооп беришет. Ачкыч сөздү колдонууну түшүнүү final, өзгөчө шилтеме өзгөрмөлөр үчүн, абдан маанилүү. Сиз ойлонуп жатып, JavaRush командасына тезирээк кайрылыңыз. Сураныч, текст редакторуңузга мазмунду жашырууга мүмкүндүк берүүчү блокту кошуңуз жана аны басканда бул мазмунду көрсөтүңүз. Жооптор:
  1. Анткени массив an object болуп саналат, бул finalan objectке шилтеме ыйгарылгандан кийин аны мындан ары өзгөртүүгө болбойт, бирок an objectтин абалын өзгөртүүгө болот.

    final int[] array = {1,2,3,4,5};
    array[0] = 9;	//ok, because change the contents of the array - {9,2,3,4,5}
    array = new int[5]; //compile error
  2. Ооба болот. Негизги нерсе - тикенектүү сөздүн finalan objectилер менен колдонулушун түшүнүү. Маани алмаштыруу үчүн ReflectionAPI колдонот.

import java.lang.reflect.Field;

class B {
    public static void main(String[] args) throws Exception {
        String value = "Old value";
        System.out.println(value);

        //Get the value field in the String class
        Field field = value.getClass().getDeclaredField("value");
        //Let's change it
        field.setAccessible(true);
        //Set new value
        field.set(value, "JavaRush".toCharArray());

        System.out.println(value);

        /* Вывод:
         * Old value
         * JavaRush
         */
    }
}
Көңүл буруңуз, эгерде биз примитивдик типтин акыркы өзгөрмөсүн ушундай жол менен өзгөртүүгө аракет кылсак, эч нерсе иштебейт. Мен сизди буга ынандырууну сунуштайм: Java классын түзүңүз, мисалы, final intталаа менен жана анын маанисин Reflection API аркылуу өзгөртүүгө аракет кылыңыз. Баарыңарга ийгorк!
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION