JavaRush /Java 博客 /Random-ZH /所以最后...
Алексей
第 32 级

所以最后...

已在 Random-ZH 群组中发布
java中有一个关键字—— final. 它可以应用于类、方法、变量(包括方法参数)。 所以最后... - 1对于一个类,这意味着该类不能有子类,即 禁止继承。这在创建(不可变)对象时非常有用immutable,例如声明Stringfinal.
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");
    }
}
对于原始类型变量,这意味着一旦分配,值就不能更改。对于引用变量,这意味着一旦分配了对象,对该对象的引用就无法更改。这很重要!链接无法更改,但对象的状态可以更改。随着 java 8 出现了这个概念 - effectively final. 它仅适用于变量(包括方法参数)。要点是,尽管明显缺少关键字final,但变量的值在初始化后并没有改变。换句话说,您可以用一个单词替换此类变量,final而不会出现编译错误。变量可以在本地类 ( )、匿名类 ( )、流 (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. 已知类Stringimmutable,类被声明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 团队。请在文本编辑器中添加一个块,该块允许您隐藏内容,并在单击它时显示该内容。答案:
  1. 因为 数组是一个对象,这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
  2. 是的你可以。关键是要理解带刺词与物体的用法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字段的 Java 类,并尝试通过 Reflection API 更改其值。祝你们好运!
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION