Java тorнде ачкыч сөз бар -
final
. Аны класстарга, методдорго, өзгөрмөлөргө (анын ичинде метод аргументтерине) колдонсо болот. Класс үчүн бул класстын субкласстары болушу мүмкүн эмес дегенди билдирет, б.а. Мураска тыюу салынат. Бул (өзгөрбөс) 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 Classes
Anonymous 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 иштеп чыгуучусу болуу жана кызыктуу жана жакшы акы төлөнүүчү жумушка ээ болуу. Ошентип, баштайлы.
-
Массив жарыяланганда ал жөнүндө эмне айта аласыз
final
? -
Белгилүү болгондой, класс
String
,immutable
класс жарыяланат , саптын мааниси ачкыч сөз менен белгиленгенfinal
массивде сакталат .char
final
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 командасына тезирээк кайрылыңыз. Сураныч, текст редакторуңузга мазмунду жашырууга мүмкүндүк берүүчү блокту кошуңуз жана аны басканда бул мазмунду көрсөтүңүз. Жооптор:
-
Анткени массив an object болуп саналат, бул
final
an 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
-
Ооба болот. Негизги нерсе - тикенектүү сөздүн
final
an 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к!
GO TO FULL VERSION