یک کلمه کلیدی در جاوا وجود دارد -
final
. می توان آن را برای کلاس ها، متدها، متغیرها (از جمله آرگومان های متد) اعمال کرد. برای یک کلاس، این بدان معنی است که کلاس نمی تواند زیر کلاس هایی داشته باشد، یعنی. ارث ممنوع است. این هنگام ایجاد immutable
اشیاء (تغییرناپذیر) مفید است، برای مثال کلاسی String
که به عنوان اعلان شده است final
.
public final class String{
}
class SubString extends String{ //Compilation error
}
همچنین لازم به ذکر است که اصلاح کننده را نمی توان برای کلاس های انتزاعی (با کلمه کلیدی 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");
}
}
برای متغیرهای نوع اولیه، این بدان معناست که پس از تخصیص، مقدار قابل تغییر نیست. برای متغیرهای مرجع، این بدان معنی است که وقتی یک شی تخصیص داده می شود، مرجع آن شی را نمی توان تغییر داد. مهم است! پیوند را نمی توان تغییر داد، اما وضعیت شی را می توان تغییر داد. با جاوا 8 مفهوم ظاهر شد - effectively final
. فقط برای متغیرها (از جمله آرگومان های متد) اعمال می شود. نکته این است که با وجود عدم وجود کلمه کلیدی final
، مقدار متغیر پس از مقداردهی اولیه تغییر نمی کند. final
به عبارت دیگر، شما می توانید یک کلمه را بدون خطای کامپایل جایگزین چنین متغیری کنید . effectively final
متغیرها را می توان در کلاس های محلی ( Local Inner Classes
)، کلاس های ناشناس ( Anonymous Inner Classes
)، جریان ها (Stream API) استفاده کرد.
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، تبدیل شدن به یک توسعه دهنده جاوا و بدست آوردن یک شغل جالب و با درآمد خوب است. بنابراین، بیایید شروع کنیم.
-
وقتی یک آرایه اعلام می شود چه می توانید بگویید
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
(بدون تغییر ارجاع به شی)؟ اینها سوالات واقعی مصاحبه هستند. و همانطور که تمرین نشان می دهد، بسیاری از آنها به اشتباه پاسخ می دهند. درک استفاده از کلمه کلیدی final
، به ویژه برای متغیرهای مرجع، بسیار مهم است. در حالی که در حال فکر کردن هستید، یک انحراف سریع به تیم JavaRush. لطفاً یک بلوک در ویرایشگر متن خود اضافه کنید که به شما امکان می دهد محتوا را پنهان کنید و وقتی روی آن کلیک می کنید، این محتوا را نشان دهید. پاسخ ها:
-
زیرا آرایه یک شی است، به این
final
معنی که پس از انتساب یک مرجع به یک شی، دیگر نمی توان آن را تغییر داد، اما وضعیت شی را می توان تغییر داد.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
با اشیا است. از 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
*/
}
}
لطفاً توجه داشته باشید که اگر بخواهیم متغیر نهایی یک نوع اولیه را به این روش تغییر دهیم، هیچ چیز جواب نمی دهد. پیشنهاد میکنم خودتان را در این مورد متقاعد کنید: برای مثال یک کلاس جاوا با final int
یک فیلد ایجاد کنید و سعی کنید مقدار آن را از طریق Reflection API تغییر دهید. همگی موفق باشید!
GO TO FULL VERSION