29

以下陈述有什么区别

String name = "Tiger";

final String name ="Tiger";

虽然String类是final类,但为什么我们需要创建一个字符串“CONSTANT”变量作为final?

4

7 回答 7

58

final在这种情况下,意味着变量name只能分配一次。再次为其分配不同的String对象会导致编译错误。

我认为这里混乱的根源是final关键字可以在几种不同的上下文中使用:

  • final class:该类不能被子类化。
  • final 方法:该方法不能被覆盖。
  • final 变量:变量只能赋值一次。

有关每种情况的示例,请参阅有关Java 中 final的 Wikipedia 文章。

于 2009-05-17T16:55:10.163 回答
4

“最终”在两种情况下的含义不同。

java.lang.String 类是最终的。这意味着你不能继承它。

变量“name”是最终的,这意味着您不能将其更改为指向不同的 String 实例。因此,非最终字符串变量不是常量,因为您可以在两次不同的时间读取它并获得不同的值。

碰巧的是,Java 字符串对象也是不可变的。这意味着您不能修改特定 String 对象所代表的值。将此与数组进行比较 - 您可以将数组对象的第一个元素替换为不同的对象,但不能将 String 对象的第一个字符替换为不同的字符。这就是 String.replace() 返回一个新字符串的原因——它不能修改旧字符串。

String 是 final 的一个原因是为了防止 String 的子类的实例(它实现了可变行为)被传递来代替 String。

但是是否可以修改特定的对象,以及是否可以将不同的对象分配给变量,是完全不同的概念。一个是 String 对象的属性,另一个是 String 变量的属性,是对 String 对象的引用。

于 2009-05-17T17:09:38.657 回答
2

请记住,Java final 关键字在这种情况下有两个用途:

  • 这意味着不能将引用设置为另一个字符串——即您不能随后执行“name = ...”;
  • 但至关重要的是,这意味着引用已正确发布到其他线程(有关更多详细信息,请参阅链接文章,或 Goetz 等人的作品,“Java Concurrency in Practice”。
于 2009-05-17T17:08:41.653 回答
1

您将 immutable 与 final 混淆了。

String 与 Integer 和 Long 一样,是一个不可变的类,因为内部数据通过封装被保护不被修改。

但是,就像 Ayman 所说,final 指的是指向字符串的指针。

于 2009-05-17T17:06:53.480 回答
1

看看final 关键字上的最后一句话

String name = "scott";
name = "tiger"; // OK

final String gender = "male";
gender = "female"; // won't compile you cannot reassign gender cause it's final
于 2009-05-18T09:04:48.367 回答
0

如果一个变量被标记为final,那么该变量的值就不能改变,即当与变量一起使用时final关键字使其成为一个常量。如果您在程序执行过程中尝试更改该变量的值,编译器会给您一个错误。

注意: 如果将引用类型的变量标记为 final,则该变量不能引用任何其他对象。但是,您可以更改对象的内容,因为只有引用本身是最终的。

来源:Java 中的最终关键字

于 2012-01-11T06:44:25.257 回答
0

推断 String 对象默认为 Final 本身就是一个模糊的陈述。Java 的基础规定,如果一个实例变量没有指向一个内存位置,它就有资格进行垃圾收集。String 对象也会发生同样的事情。它们是不可变的,但它们的引用可以更改。为了克服这个问题,我们可以使用 "Final String s1 = "Final String" " 关键字不允许对 s1 进行任何赋值,除非在首次声明时,使其真正不可变。

public class DemoStringF 
{
    String s1; //Declaring an Instance Variable to type String. 

    public static void main(String... args)
    {
        DemoStringF d = new DemoStringF ();
        d.s1 = "Intializing s1 here"; //Initializing the s1

          System.out.println("Value ref. by s1 is " +d.s1); //Displays the String 
                                                            by which s1 is 
                                                            initialized.

         System.out.println("Value of s1 is " +d.s1.hashCode()); //Displays the 
                                                                 value of the s1.

         d.s1 = d.s1.concat(" Adding String to s1"); //Changing the value ref. by 
                                                       s1.
        System.out.println("Value ref. by s1 after concat() is " +d.s1); 
                                                    //Displays a new value of s1.


        System.out.println("Value of s1 is " +d.s1.hashCode()); //Displays 
                                                            the value of the s1.
    }

    }

在此处输入图像描述

于 2020-05-29T16:48:53.170 回答