JavaRush /Java блогы /Random-KK /Java тіліндегі қорытынды, тұрақты және өзгермейтін

Java тіліндегі қорытынды, тұрақты және өзгермейтін

Топта жарияланған
Сәлеметсіз бе! «Модификатор» сөзі сізге бұрыннан таныс. Кем дегенде, сіз кіру модификаторларын (жалпыға ортақ, жеке) және статикалық модификаторды кездестірдіңіз. Бүгін біз арнайы соңғы модификатор туралы сөйлесетін боламыз . Бұл біздің бағдарламамыздың тұрақты, бір мәнді, өзгермейтін мінез-құлықты қажет ететін салаларын «цементтеу» деп айтуға болады. Оны бағдарламамыздың үш саласында қолдануға болады: сыныптар, әдістер және айнымалылар. Java тілінде өзгермейтін: соңғы, тұрақтылар және өзгермейтін - 2 Оларды бір-бірлеп қарастырайық. Егер сынып декларациясында соңғы модификатор болса , бұл осы сыныптан мұраға алмайтыныңызды білдіреді. Алдыңғы дәрістерде біз тұқым қуалаудың қарапайым мысалын көрдік: бізде ата-аналар класы Animalжәне екі бала сыныбы болды - CatжәнеDog
public class Animal {
}

public class Cat extends Animal {
   //..поля и методы класса Cat
}

public class Dog extends Animal {

   //..поля и методы класса Dog
}
AnimalДегенмен, сынып үшін модификаторды көрсетсек , сыныптар одан да finalмұра ала алмайды . CatDog
public final class Animal {

}

public class Cat extends Animal {

   //ошибка! Cannot inherit from final Animal
}
Компилятор бірден қате шығарады. Java-да қазірдің өзінде енгізілген көптеген сыныптар бар final. Сіз үнемі қолданатындардың ішіндегі ең танымалы String. Сонымен қатар, егер сынып деп жарияланса final, оның барлық әдістері де болады final. Бұл нені білдіреді? Егер әдіс үшін модификатор көрсетілсе final, бұл әдісті қайта анықтау мүмкін емес. Мысалы, бізде Animalәдісті анықтайтын класс бар voice(). Дегенмен, иттер мен мысықтар басқаша «сөйлейді». Сондықтан, әр сыныпта - Catжәне Dog- әдісті жасаймыз voice(), бірақ оны басқаша жүзеге асырамыз.
public class Animal {

   public void voice() {
       System.out.println("Voice!");
   }
}

public class Cat extends Animal {

   @Override
   public void voice() {
       System.out.println("Meow!");
   }
}

public class Dog extends Animal {

   @Override
   public void voice() {
       System.out.println("Woof!");
   }
}
Сыныптарда Catжәне Dogбіз ата-аналық сыныптың әдісін жоққа шығардық. Енді жануар қандай сынып an objectісіне байланысты дауыстайды:
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();
       Dog dog = new Dog();

       cat.voice();
       dog.voice();
   }
}
Қорытынды: Мия! Уф! Дегенмен, егер Animalбіз сыныптағы әдісті voice()деп жарияласақ final, оны басқа сыныптарда қайта анықтау мүмкін болмайды:
public class Animal {

   public final void voice() {
       System.out.println("Voice!");
   }
}


public class Cat extends Animal {

   @Override
   public void voice() {//ошибка! final-метод не может быть переопределен!
       System.out.println("Meow!");
   }
}
voice()Содан кейін біздің нысандар ата-аналық сыныпта анықталған әдісті қолдануға мәжбүр болады :
public static void main(String[] args) {

   Cat cat = new Cat();
   Dog dog = new Dog();

   cat.voice();
   dog.voice();
}
Қорытынды: Дауыс! Дауыс! Енді final-айнымалылар туралы. Әйтпесе олар тұрақты деп аталады . Біріншіден (және ең бастысы) тұрақтыға тағайындалған бірінші мәнді өзгерту мүмкін емес. Ол бір рет және мәңгілікке тағайындалады.
public class Main {

   private static final int CONSTANT_EXAMPLE = 333;

   public static void main(String[] args) {

       CONSTANT_EXAMPLE = 999;//ошибка! Нельзя присвоить новое meaning final-переменной!
   }
}
Тұрақты мәнді бірден инициализациялау қажет емес. Мұны кейінірек жасауға болады. Бірақ бірінші тағайындалған мән мәңгі қалады.
public static void main(String[] args) {

   final int CONSTANT_EXAMPLE;

   CONSTANT_EXAMPLE = 999;//так делать можно
}
Екіншіден, айнымалының атына назар аударыңыз. Java тұрақтыларының басқа атау конвенциясы бар. Бұл біз үйреніп қалған түйе корпусы емес. Тұрақты айнымалы болған жағдайда, біз оны тұрақтыМысалы деп атайтын едік, бірақ тұрақтылардың атаулары бас әріптермен жазылады, ал сөздердің арасында (олар бірнеше болса) астын сызу - “ТҰРАҚТЫ_МЫСАЛ”. Тұрақтылар не үшін қажет? Мысалы, егер сіз бағдарламада тұрақты мәнді үнемі қолдансаңыз, олар пайдалы болады. Сіз тарихта қалуды және жалғыз «The Witcher 4» ойынын жазуды шештіңіз делік. Ойын үнемі басты кейіпкердің атын пайдаланады - «Ривияның Геральты». Бұл жолды және басқа кейіпкерлердің есімдерін тұрақты мәнге бөлген дұрыс: сізге қажет мән бір жерде сақталады және оны миллионыншы рет тергенде қателеспейтін боласыз.
public class TheWitcher4 {

   private static final String GERALT_NAME = "Геральт из Ривии";
   private static final String YENNEFER_NAME = "Йеннифэр из Венгерберга";
   private static final String TRISS_NAME = "Трисс Меригольд";

   public static void main(String[] args) {

       System.out.println("Ведьмак 4");
       System.out.println("Это уже четвертая часть Ведьмака, а " + GERALT_NAME + " ниHow не определится кто ему" +
               " нравится больше: " + YENNEFER_NAME + " or " + TRISS_NAME);

       System.out.println("Но если вы никогда не играли в Ведьмака - начнем сначала.");
       System.out.println("Главного героя зовут " + GERALT_NAME);
       System.out.println(GERALT_NAME + " - ведьмак, охотник на чудовищ");
   }
}
Қорытынды:
Ведьмак 4
Это уже четвертая часть Ведьмака, а Геральт из Ривии ниHow не определится, кто ему нравится больше: Йеннифэр из Венгерберга or Трисс Меригольд.
Но если вы никогда не играли в Ведьмака — начнем сначала.
Главного героя зовут Геральт из Ривии
Геральт из Ривии — ведьмак, охотник на чудовищ
Біз кейіпкерлердің атын тұрақтыға бөлдік, енді біз оларды міндетті түрде қате жібермейміз және оларды әр уақытта қолмен жазудың қажеті жоқ. Тағы бір плюс: егер ақыр соңында айнымалының мәнін бүкіл бағдарлама бойынша өзгерту қажет болса, оны бүкіл codeта қолмен қайта жасаудың орнына, оны бір жерде орындау жеткілікті :)

Өзгермейтін түрлері

Java-да жұмыс істеген уақытыңызда сіз бағдарламашы барлық нысандардың күйін толығымен дерлік басқаратынына үйреніп қалған шығарсыз. Wanted - an object құрылды Cat. Қаласам, атын өзгерттім. Қаласа жасын өзгертті, әлде басқасын. Бірақ Java-да арнайы күйі бар бірнеше деректер түрлері бар. Олар өзгермейтін немесе өзгермейтін . Бұл дегеніміз, егер сынып өзгермейтін болса, оның an objectілерінің күйін өзгерту мүмкін емес. Мысалдар? Сіз таң қалуыңыз мүмкін, бірақ Immutable класының ең танымал мысалы - String! Жолдың мәнін өзгерте алмайтын сияқтымыз ба? Тырысып көрейік:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1 = "I love Python";//но поведение str1 ниHow не влияет на str2
   System.out.println(str2);//str2 продолжает указывать на строку "I love Java", хотя str1 уже указывает на другой an object
}
Қорытынды: Мен Java-ны жақсы көремін Мен Java-ны жақсы көремін Біз жазғаннан кейін:
str1 = "I love Python";
«I love Java» жолы бар нысан өзгерген жоқ және ешқайда кеткен жоқ. Ол қауіпсіз және оның ішінде бұрынғыдай мәтін бар. Код:
str1 = "I love Python";
жай ғана басқа нысанды жасады және енді айнымалы str1оған нұсқайды. Бірақ біз «Мен Java-ны жақсы көремін» нысанына ешқандай әсер ете алмаймыз . Жарайды, басқаша көрейік! Класс Stringәдістерге толы, олардың кейбіреулері қатардың күйін өзгертетін сияқты! Мысалы, әдіс бар replace(). Жолымыздағы «Java» сөзін «Python» сөзіне ауыстырайық!
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1.replace("Java", "Python");//попробуем изменить состояние str1, заменив слово "Java" на “Python”
   System.out.println(str2);
}
Қорытынды: Мен Java-ны жақсы көремін Мен Java-ны жақсы көремін. Бұл қайталанбады! Мүмкін қисық әдісі жұмыс істемейді? Басқасын қолданып көрейік. Мысалы, substring(). Жіберілген таңбалардың сандарына негізделген жолды кеседі. Бізді алғашқы 10 таңбаға дейін қысқартайық:
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   str1.substring(10);//обрезаем исходную строку
   System.out.println(str2);
}
Қорытынды: Мен Java тілін жақсы көремін Мен Java-ны жақсы көремін Java тілінде өзгермейтін: соңғы, тұрақтылар және өзгермейтін - 3 Ештеңе өзгерген жоқ. Және ол болмауы керек. Біз айтқандай, нысандар Stringөзгермейді. Сонда бұл барлық сынып әдістері дегеніміз не String? Олар сызықты кесуге, ондағы таңбаларды өзгертуге және т.б. Егер ештеңе болмаса, олар не үшін қажет? Олар істей алады! Бірақ олар әр жолы жаңа жол нысанын қайтарады. Жазудың пайдасы жоқ:
str1.replace("Java", "Python");
- бастапқы нысанды өзгертпейсіз. Бірақ әдістің нәтижесін жаңа анықтамалық айнымалыға жазсаңыз, айырмашылықты бірден көресіз!
public static void main(String[] args) {

   String str1 = "I love Java";

   String str2 = str1;//обе переменные-ссылки указывают на одну строку.
   System.out.println(str2);

   String str1AfterReplacement =  str1.replace("Java", "Python");
   System.out.println(str2);

   System.out.println(str1AfterReplacement);
}
Бұл әдістердің барлығы жұмыс істейтін жалғыз әдіс String. «I love Java» нысанымен ештеңе істей алмайсыз . Жай ғана жаңа нысан жасаңыз және жазыңыз: «Жаңа нысан = «Мен Java-ны жақсы көремін» нысанымен кейбір манипуляциялардың нәтижесі ». Басқа қандай түрлер Өзгермейтін? Енді сіз міндетті түрде есте сақтауыңыз керек нәрсе - қарабайыр түрлерге қатысты барлық орауыш сыныптары өзгермейді. Integer, Byte, Character, Short, Boolean, Long, Double, Float- осы кластардың барлығы Өзгермейтін an objectілерді жасайды. Бұған үлкен сандарды жасау үшін қолданылатын сыныптар да кіреді - BigIntegerжәне BigDecimal. Жақында біз ерекше жағдайларды бастан өткердік StackTrace. Сонымен: java.lang.StackTraceElement класының нысандары да өзгермейді. Бұл қисынды: егер біреу біздің стектегі деректерді өзгерте алса, ол онымен барлық жұмысты жоққа шығаруы мүмкін. Біреу StackTrace ішіне кіріп , OutOfMemoryError файлын FileNotFoundException күйіне өзгертеді деп елестетіп көріңіз . Сіз осы стекпен жұмыс істеп, қатенің себебін іздеуіңіз керек. Ал бағдарлама файлдарды мүлде пайдаланбайды :) Сондықтан қауіпсіз жақта болу үшін бұл нысандар өзгермейтін етіп жасалды. StackTraceElement көмегімен бұл азды-көпті түсінікті. Неліктен біреу жолдарды өзгермейтін етіп жасағысы келеді? Егер олардың құндылықтарын өзгерту мүмкін болса, қандай мәселе болар еді. Бұл одан да ыңғайлы болар еді:/ Мұның бірнеше себептері бар. Біріншіден, жадты сақтау. Өзгермейтін жолдарды орналастыруға болады String Poolжәне жаңаларын жасаудың орнына бірдей жолдарды әр уақытта пайдалануға болады. Екіншіден, қауіпсіздік. Мысалы, кез келген бағдарламадағы логиндер мен құпия сөздердің көпшілігі жолдар болып табылады. Оларды өзгерту мүмкіндігі авторизацияға қатысты мәселелерге әкелуі мүмкін. Басқа да себептер бар, бірақ біз Java тілін үйренуде оларға әлі жете қойған жоқпыз — кейінірек ораламыз.
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION