字符串和常量

29

以下语句之间有什么区别?

String name = "Tiger";

final String name ="Tiger";

尽管String类是一个final类,但为什么我们需要创建一个名为"CONSTANT"的String常量?


5
这里指的是将字符串设为final的引用,而不是字符串本身被设为final。 - Peter Lawrey
7个回答

59

final 在这个语境中的意思是变量 name 只能被赋值一次。再次给它赋一个不同的 String 对象会导致编译错误。

我认为这里混淆的源头在于 final 关键字可以在几个不同的上下文中使用:

  • final class:该类无法被继承。
  • final method:该方法无法被覆盖。
  • final variable:该变量只能被赋值一次。

请参见维基百科关于Java中final的用法,里面有每种情况的示例。


请记住,“final”也涉及到对其他线程的安全发布(请参见下面我的答案)。 - Neil Coffey

4
"

final" 在这两种情况下的含义不同。

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

变量"name"是final的,这意味着你不能将它更改为指向不同的String实例。因此,非final的String变量不是常量,因为您可能在两个不同的时间读取它并获取不同的值。

恰好Java字符串对象也是不可变的。这意味着您无法修改特定String对象所表示的值。与数组相比较——您可以将数组对象的第一个元素替换为另一个对象,但是您无法使用不同的字符替换String对象的第一个字符。这就是为什么String.replace()返回一个新的字符串的原因——它无法修改旧的字符串。

String是final的原因之一是防止实现可变行为的String子类的实例被传递代替String。

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

"

2

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

  • 它意味着引用不能被设置为另一个字符串——即您不能随后执行“name = ...”;
  • 但是至关重要的是,它意味着该引用已正确发布到其他线程(有关更多详细信息,请参见链接文章或类似Goetz等人的作品,“Java并发实践”)。

是的,在并发应用程序中,final 的语义非常重要,而在普通的 Java 应用程序中则不太重要,因为 Java 程序员倾向于接受可变性。 - egaga

1

你将immutable和final混淆了。

String、Integer和Long都是不可变的类,因为通过封装保护了内部数据不被修改。

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


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

0

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

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

来源:Java中的Final关键字


0
推断字符串对象默认为Final本身就是一个模糊的陈述。Java的基础规定,如果实例变量没有指向内存位置,则变得适合垃圾回收。String对象也会发生同样的事情。它们是不可变的,但是它们的引用可以被更改。为了克服这个问题,我们可以使用“Final String s1 =“Final String””,final关键字将不允许在第一次声明时以外的任何时间对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.
    }

    }

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接